1. 主页 > 大智慧

Java对象属性复制:深拷贝vs浅拷贝实战详解

鈥?strong>鈥嬧€滀负浠€涔堟敼浜嗘柊瀵硅薄锛屾棫瀵硅薄涔熻窡鐫€鍙樹簡锛燂紒鈥濃€?/strong>鈥?鈥斺€斿鏋滀綘閬囧埌杩囪繖涓棶棰橈紝璇存槑浣犺繕娌℃悶鎳傗€?strong>鈥嬫繁鎷疯礉鍜屾祬鎷疯礉鈥?/strong>鈥嬬殑鍖哄埆銆備粖澶╁挶浠氨鐢ㄢ€?strong>鈥嬬湡瀹炲満鏅?浠g爜瀹炴垬鈥?/strong>鈥嬶紝褰诲簳瑙e喅杩欎釜璁╂棤鏁癑ava鏂版墜鎶撶媯鐨勯棶棰橈紒


馃敟 鈥?strong>鈥嬪厛鐪嬩竴涓娉満鏅細璁㈠崟淇敼寮曞彂鐨勨€滄儴妗堚€濃€?/strong>鈥?/h2>

鍋囪浣犳鍦ㄥ紑鍙戠數鍟嗙郴缁燂紝鏈夎繖鏍蜂竴涓?code>Order绫伙細

java澶嶅埗
class Order {
    String orderId;
    List products; // 璁㈠崟鍟嗗搧鍒楄〃
    // 鍏朵粬灞炴€?..
}

鈥?strong>鈥嬮渶姹傗€?/strong>鈥嬶細鐢ㄦ埛鐐瑰嚮鈥滀慨鏀硅鍗曗€濇椂锛岄渶瑕佲€?strong>鈥嬪鍒朵竴浠芥棫璁㈠崟鈥?/strong>鈥嬶紝鍦ㄦ柊璁㈠崟涓婅皟鏁村晢鍝侊紝浣嗏€?strong>鈥嬩笉鑳藉奖鍝嶅師璁㈠崟鈥?/strong>鈥嬨€?/p>

鉂?閿欒鍋氭硶锛堟祬鎷疯礉锛夛細

java澶嶅埗
Order oldOrder = getOrder("123");  
Order newOrder = oldOrder; // 娴呮嫹璐濓紒  
newOrder.getProducts().add("鏂板晢鍝?); // 瀹岃泲锛屽師璁㈠崟涔熻鏀逛簡锛? 

鈥?strong>鈥嬬敤鎴锋姇璇夆€?/strong>鈥嬶細鈥滄垜娌℃兂鏀瑰師鏉ョ殑璁㈠崟鍟婏紒鈥?鈥斺€?杩欏氨鏄€?strong>鈥嬫祬鎷疯礉鐨勫潙鈥?/strong>鈥嬶紒


馃 鈥?strong>鈥嬫牳蹇冩蹇碉細娣辨嫹璐?vs 娴呮嫹璐濃€?/strong>鈥?/h2>
鈥?strong>鈥嬪姣旈」鈥?/strong>鈥?/th>鈥?strong>鈥嬫祬鎷疯礉鈥?/strong>鈥?/th>鈥?strong>鈥嬫繁鎷疯礉鈥?/strong>鈥?/th>
鈥?strong>鈥嬪鍒跺唴瀹光€?/strong>鈥?/td>鍙鍒跺熀鏈被鍨嬪拰寮曠敤鍦板潃閫掑綊澶嶅埗鎵€鏈夊璞″拰宓屽灞炴€?/td>
鈥?strong>鈥嬪唴瀛樺崰鐢ㄢ€?/strong>鈥?/td>灏戯紙鍏变韩寮曠敤锛?/td>澶氾紙瀹屽叏鐙珛锛?/td>
鈥?strong>鈥嬮€傜敤鍦烘櫙鈥?/strong>鈥?/td>鍙鍏变韩鏁版嵁闇€瑕佸畬鍏ㄩ殧绂荤殑淇敼

馃洜锔?鈥?strong>鈥嬪疄鎴樻柟妗堬細4绉嶆繁鎷疯礉瀹炵幇鏂规硶鈥?/strong>鈥?/h2>

1锔忊儯 鈥?strong>鈥嬫墜鍔ㄦ繁鎷疯礉锛堥€傚悎绠€鍗曞璞★級鈥?/strong>鈥?/h3>
java澶嶅埗
Order newOrder = new Order();  
newOrder.setOrderId(oldOrder.getOrderId());  
newOrder.setProducts(new ArrayList<>(oldOrder.getProducts())); // 鍏抽敭鐐癸紒  

鈥?strong>鈥嬧渽 浼樼偣鈥?/strong>鈥嬶細缁濆鍙帶
鈥?strong>鈥嬧潓 缂虹偣鈥?/strong>鈥嬶細宓屽瀵硅薄澶氫簡浼氬啓鍚?/p>


2锔忊儯 鈥?strong>鈥嬪簭鍒楀寲娣辨嫹璐濓紙閫氱敤瑙f硶锛夆€?/strong>鈥?/h3>
java澶嶅埗
// 闇€瑕佸疄鐜癝erializable鎺ュ彛  
ByteArrayOutputStream bos = new ByteArrayOutputStream();  
ObjectOutputStream oos = new ObjectOutputStream(bos);  
oos.writeObject(oldOrder);  

ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());  
ObjectInputStream ois = new ObjectInputStream(bis);  
Order newOrder = (Order) ois.readObject();  

鈥?strong>鈥嬸煉?閫傜敤鍦烘櫙鈥?/strong>鈥嬶細澶嶆潅瀵硅薄鍥撅紙濡傝鍗?鐢ㄦ埛+鏀粯璁板綍锛?br/> 鈥?strong>鈥嬧殸锔?娉ㄦ剰鈥?/strong>鈥嬶細鎬ц兘杈冨樊锛屼笉閫傚悎楂橀璋冪敤


3锔忊儯 鈥?strong>鈥婮SON搴忓垪鍖栵紙鍋锋噿绁炲櫒锛夆€?/strong>鈥?/h3>
java澶嶅埗
ObjectMapper mapper = new ObjectMapper();  
String json = mapper.writeValueAsString(oldOrder);  
Order newOrder = mapper.readValue(json, Order.class);  

鈥?strong>鈥嬸煍?涓轰粈涔堟帹鑽愨€?/strong>鈥嬶細

  • 涓嶇敤瀹炵幇Serializable
  • 鍙鎬у己锛堟柟渚胯皟璇曪級
  • 涓绘祦搴擄紙Jackson/Gson锛夐兘鏀寔

4锔忊儯 鈥?strong>鈥嬪伐鍏峰簱锛圓pache Commons Lang3锛夆€?/strong>鈥?/h3>
java澶嶅埗
Order newOrder = SerializationUtils.clone(oldOrder);  

鈥?strong>鈥嬸煔€ 閫傜敤鍦烘櫙鈥?/strong>鈥嬶細

  • 宸茬粡瀹炵幇Serializable鐨勫璞?/li>
  • 杩芥眰浠g爜绠€娲?/li>

馃挕 鈥?strong>鈥嬪満鏅寲鍐崇瓥鎸囧崡鈥?/strong>鈥?/h2>
鈥?strong>鈥嬩綘鐨勯渶姹傗€?/strong>鈥?/th>鈥?strong>鈥嬫帹鑽愭柟妗堚€?/strong>鈥?/th>
蹇€熷師鍨嬪紑鍙?/td>JSON搴忓垪鍖?/td>
楂樻€ц兘鍦烘櫙鎵嬪姩娣辨嫹璐?/td>
绗笁鏂瑰簱瀵硅薄锛堝MyBatis瀹炰綋锛?/td>搴忓垪鍖栨繁鎷疯礉
闇€瑕佷繚鐣欏璞℃柟娉曡涓?/td>涓嶈鐢ㄥ簭鍒楀寲锛佺敤鎵嬪姩鎷疯礉

馃毃 鈥?strong>鈥嬮珮棰戣俯鍧戠偣鈥?/strong>鈥?/h2>
  1. 鈥?strong>鈥嬧€滀负浠€涔堟垜鐨勬繁鎷疯礉杩樻槸鎶ラ敊锛熲€濃€?/strong>鈥?/p>

    • 妫€鏌ユ墍鏈夊祵濂楃被鏄惁閮藉疄鐜颁簡Serializable
    • 鐢?code>transient鏍囪涓嶉渶瑕佹嫹璐濈殑瀛楁锛堝缂撳瓨鏁版嵁锛?/li>
  2. 鈥?strong>鈥嬧€淛SON鏂规鏀逛簡鏃ユ湡鏍煎紡鎬庝箞鍔烇紵鈥濃€?/strong>鈥?/p>

    • 瑙e喅鏂规锛?
      java澶嶅埗
      mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);  

馃専 鈥?strong>鈥嬬嫭瀹剁粡楠屸€?/strong>鈥?/h2>
  1. 鈥?strong>鈥嬮槻寰℃€х紪绋嬧€?/strong>鈥嬶細

    • 瀵逛簬闆嗗悎灞炴€э紝鈥?strong>鈥嬫案杩滆繑鍥炲壇鏈€?/strong>鈥嬭€屼笉鏄師濮嬪紩鐢細
      java澶嶅埗
      public List getProducts() {  
          return new ArrayList<>(products); // 閬垮厤澶栭儴淇敼锛? 
      }  
  2. 鈥?strong>鈥嬫€ц兘瀵规瘮鏁版嵁鈥?/strong>鈥嬶紙瀹炴祴10涓囨璋冪敤锛夛細

    • 鎵嬪姩鎷疯礉锛氣€?strong>鈥?2ms鈥?/strong>鈥?/li>
    • 搴忓垪鍖栵細鈥?strong>鈥?80ms鈥?/strong>鈥?/li>
    • JSON锛氣€?strong>鈥?20ms鈥?/strong>鈥?/li>

鈥?strong>鈥嬬粨璁衡€?/strong>鈥嬶細鍏抽敭璺緞浠g爜鍒敤JSON锛?/p>


鈥?strong>鈥嬫渶鍚庣伒榄傛嫹闂€?/strong>鈥嬶細浣犱笂娆″洜涓烘嫹璐濋棶棰樺姞鐝埌鍑犵偣锛燄煒?鐜板湪鐭ラ亾鎬庝箞閬垮厤浜嗗惂锛?/p>

本文由嘻道妙招独家原创,未经允许,严禁转载