日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

原型模式 —— Java的赋值、浅克隆和深度克隆的区别

發(fā)布時間:2023/12/13 java 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 原型模式 —— Java的赋值、浅克隆和深度克隆的区别 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

賦值 直接? = ,克隆 clone

假如說你想復(fù)制一個簡單變量。很簡單:

int a= 5; int b= a;

b = 6;

這樣 a == 5, b == 6

不僅僅是int類型,其它七種原始數(shù)據(jù)類型(boolean,char,byte,short,float,double.long)同樣適用于該類情況。

但是如果你復(fù)制的是一個對象、list集合的情況下,情況就有些復(fù)雜了。

?

class Student { private int number; public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } } public class Test { public static void main(String args[]) { Student stu1 = new Student(); stu1.setNumber(12345); Student stu2 = stu1; System.out.println("學(xué)生1:" + stu1.getNumber()); System.out.println("學(xué)生2:" + stu2.getNumber()); } }結(jié)果:學(xué)生1:12345 學(xué)生2:12345

?

這就怪了,為什么改變學(xué)生2的學(xué)號,學(xué)生1的學(xué)號也發(fā)生了變化呢?

原因出在(stu2 = stu1) 這一句。該語句的作用是將stu1的引用賦值給stu2,

這樣,stu1和stu2指向內(nèi)存堆中同一個對象。如圖:

?

?

?

?

?

要做到 賦值的兩個對象之間的內(nèi)存地址重新定義

實現(xiàn)對象克隆有兩種方式:

??1). 實現(xiàn)Cloneable接口并重寫Object類中的clone()方法;?

class Address implements Cloneable { private String add; public String getAdd() { return add; } public void setAdd(String add) { this.add = add; } @Override public Object clone() { // 下面 這個是重點Address addr = null; try{ addr = (Address)super.clone(); }catch(CloneNotSupportedException e) { e.printStackTrace(); } return addr; } }

?

2). 實現(xiàn)Serializable接口,通過對象的序列化和反序列化實現(xiàn)克隆,可以實現(xiàn)真正的深度克隆。

如果引用類型里面還包含很多引用類型,或者內(nèi)層引用類型的類里面又包含引用類型,使用clone方法就會很麻煩。這時我們可以用序列化的方式來實現(xiàn)對象的深克隆。

public class Outer implements Serializable{private static final long serialVersionUID = 369285298572941L; //最好是顯式聲明IDpublic Inner inner;//Discription:[深度復(fù)制方法,需要對象及對象所有的對象屬性都實現(xiàn)序列化] public Outer myclone() {Outer outer = null;try { // 將該對象序列化成流,因為寫在流里的是對象的一個拷貝,而原對象仍然存在于JVM里面。所以利用這個特性可以實現(xiàn)對象的深拷貝ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(baos);oos.writeObject(this);// 將流序列化成對象ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bais);outer = (Outer) ois.readObject();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}return outer;} }

?

?

實現(xiàn)對象克隆有兩種方式:

??1). 實現(xiàn)Cloneable接口并重寫Object類中的clone()方法;

??2). 實現(xiàn)Serializable接口,通過對象的序列化和反序列化實現(xiàn)克隆,可以實現(xiàn)真正的深度克隆。

注意:基于序列化和反序列化實現(xiàn)的克隆不僅僅是深度克隆,更重要的是通過泛型限定,可以檢查出要克隆的對象是否支持序列化,這項檢查是編譯器完成的,不是在運行時拋出異常,這種是方案明顯優(yōu)于使用Object類的clone方法克隆對象。讓問題在編譯的時候暴露出來總是優(yōu)于把問題留到運行時。

注: 集合的clone,ArrayList 默認實現(xiàn)了cloneable,但是List<A> A對象不是深度克隆,A對象的內(nèi)容也是使用同一個內(nèi)存地址,所以A對象也必須實現(xiàn)clone

?

?

轉(zhuǎn)載至:https://www.cnblogs.com/lemon-flm/p/9565695.html

轉(zhuǎn)載于:https://www.cnblogs.com/mh-study/p/10514010.html

總結(jié)

以上是生活随笔為你收集整理的原型模式 —— Java的赋值、浅克隆和深度克隆的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。