先看一個例子html
User user1 = new User(); user1.setId("111"); Map<String, User> map1 = new HashMap<>(); map1.put("a", user1); Map<String, User> map2 = new HashMap<>(); map2.putAll(map1); User user2 = map2.get("a"); user2.setId("222"); System.out.println("user1 id:"+user1.getId()); System.out.println("user2 id:"+user2.getId());
user1 id:222
user2 id:222
能夠看到改了map2裏的對象,map1裏的也跟着改了。java
所謂淺複製:則是隻複製對象的引用,兩個引用仍然指向同一個對象,在內存中佔用同一塊內存。被複制對象的全部變量都含有與原來的對象相同的值,而全部的對其餘對象的引用仍然指向原來的對象。換言之,淺複製僅僅複製所拷貝的對象,而不復制它所引用的對象。 post
深複製:被複制對象的全部變量都含有與原來的對象相同的值,除去那些引用其餘對象的變量。那些引用其餘對象的變量將指向被複制過的新對象,而再也不是原有的那些被引用的對象。換言之,深複製把要複製的對象所引用的對象都複製了一遍。url
注意:直接map2=map1或者map2=map1.clone(),這些都是淺複製,另外map沒有實現Cloneable接口,不過hashmap實現了。spa
關於java裏克隆的理解:Java中的Cloneable接口理解code
利用java的序列化和反序列化,具體參閱java序列化反序列化深刻探究(轉)htm
1 User user1 = new User(); 2 user1.setId("111"); 3 HashMap<String, User> map1 = new HashMap<>(); 4 map1.put("a", user1); 5 6 HashMap<String, User> map2 = null; 7 ObjectOutputStream oos = null; 8 ObjectInputStream ois = null; 9 try { 10 oos = new ObjectOutputStream(new FileOutputStream("tempfile")); 11 oos.writeObject(map1); 12 13 ois = new ObjectInputStream(new FileInputStream("tempfile")); 14 map2 = (HashMap<String, User>) ois.readObject(); 15 } catch (IOException e) { 16 e.printStackTrace(); 17 } catch (ClassNotFoundException e) { 18 e.printStackTrace(); 19 } finally { 20 if (oos != null) { 21 try { 22 oos.close(); 23 } catch (IOException e) { 24 e.printStackTrace(); 25 } 26 } 27 if(ois != null){ 28 try { 29 ois.close(); 30 } catch (IOException e) { 31 e.printStackTrace(); 32 } 33 } 34 } 35 36 37 User user2 = map2.get("a"); 38 user2.setId("222"); 39 40 System.out.println("user1 id:"+user1.getId()); 41 System.out.println("user2 id:"+user2.getId());
user1 id:111
user2 id:222
更多知識能夠參閱:Java中的不可變類理解對象