java对象深复制、浅复制(深拷贝、浅拷贝)的理解

先看一个例子

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里的也跟着改了。

所谓浅复制:则是只复制对象的引用,两个引用仍然指向同一个对象,在内存中占用同一块内存。被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所拷贝的对象,而不复制它所引用的对象。         

深复制:被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍

注意:直接map2=map1或者map2=map1.clone(),这些都是浅复制,另外map没有实现Cloneable接口,不过hashmap实现了。

关于java里克隆的理解:Java中的Cloneable接口理解

如何实现深拷贝?

利用java的序列化和反序列化,具体参阅java序列化反序列化深入探究(转)

 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中的不可变类理解

posted @ 2017-02-18 23:49  夏威夷8080  阅读(1073)  评论(0编辑  收藏  举报