Java中的深拷貝與淺拷貝
深拷貝和淺拷貝區別是什么?
數據分為基本數據類型和引用數據類型。基本數據類型:數據直接存儲在棧中;引用數據類型:存儲在棧中的是對象的引用地址,真實的對象數據存放在堆內存里。
淺拷貝:對于基礎數據類型:直接復制數據值;對于引用數據類型:只是復制了對象的引用地址,新舊對象指向同一個內存地址,修改其中一個對象的值,另一個對象的值隨之改變。
深拷貝:對于基礎數據類型:直接復制數據值;對于引用數據類型:開辟新的內存空間,在新的內存空間里復制一個一模一樣的對象,新老對象不共享內存,修改其中一個對象的值,不會影響另一個對象。
深拷貝相比于淺拷貝速度較慢并且花銷較大。
深拷貝/淺拷貝分析案例
淺拷貝實現 Cloneable,深拷貝是通過實現 Serializable 讀取二進制流
深拷貝實現:
首先Person 對象實現 Serializable 接口,然后自定義深拷貝方法 deepClone():
/** * 深拷貝 * * 注意:要實現序列化接口 * @return */ public Person deepClone() { try { // 輸出 (序列化) ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(this); // 輸入 (反序列化) ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); Person person = (Person) ois.readObject(); return person; } catch (Exception e) { e.printStackTrace(); return null; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
接下來驗證一下深拷貝是否成功:
@Test public void testPropotype() throws CloneNotSupportedException { Person person1 = new Person(); person1.setAge(22); person1.setName("csp"); // 初始化list 并為其加入數據 person1.setList(new ArrayList<>()); person1.getList().add("aaa"); person1.getList().add("bbb"); System.out.println("person1:"+person1); //-----------------------------淺拷貝------------------------------- //Person person2 = person1.clone(); //-----------------------------深拷貝------------------------------- Person person2 = person1.deepClone(); person2.setName("hzw"); // 給peron2 中的list添加一條數據 person2.getList().add("ccc"); System.out.println("person2"+person2); System.out.println("person1:"+person1); boolean flag1 = person1 == person2; System.out.println("person1 和 person2 的 引用地址是否相同: " + flag1); boolean flag2 = person1.getList() == person2.getList(); System.out.println("person1 和 person2 的 list 引用地址是否相同: " + flag2); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
輸出結果:
空參構造函數調用... person1:Person{name='csp', age=22, list=[aaa, bbb]} person2Person{name='hzw', age=22, list=[aaa, bbb, ccc]} person1:Person{name='csp', age=22, list=[aaa, bbb]} person1 和 person2 的 引用地址是否相同: false person1 和 person2 的 list 引用地址是否相同: false
1
2
3
4
5
6
由結果可得出:深拷貝 person2 所得到的 list 內存地址和原來person1 中的內存地址是不同的,深拷貝成功!
Java 數據結構
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。