是時候捋一捋 Java 的深淺複製了
在開發、刷題、面試中,我們可能會遇到將一個物件的屬性賦值到另一個物件的情況,這種情況就叫做複製。複製與Java記憶體結構息息相關,搞懂Java深淺複製是很必要的!
在物件的複製中,很多初學者可能搞不清到底是複製了引用還是複製了物件。在複製中這裡就分為引用複製、淺複製、深複製進行講述。
引用複製
引用複製會生成一個新的物件引用地址,但是兩個最終指向依然是同一個物件。如何更好的理解引用複製呢?很簡單,就拿我們人來說,通常有個姓名,但是不同場合、人物對我們的叫法可能不同,但我們很清楚哪些名稱都是屬於"我"的!
當然,透過一個程式碼示例讓大家領略一下(為了簡便就不寫get、set等方法):
class Son {
String name;
int age;
public Son(String name, int age) {
this.name = name;
this.age = age;
}
}public class test {
public static void main(String[] args) {
Son s1 = new Son("son1", 12);
Son s2 = s1;
s1.age = 22;
System.out.println(s1);
System.out.println(s2);
System.out.println("s1的age:" + s1.age);
System.out.println("s2的age:" + s2.age);
System.out.println("s1==s2" + (s1 == s2));//相等
}
}
輸出的結果為:
Son@135fbaa4
Son@135fbaa4
s1的age:22
s2的age:22true
淺複製
如何建立一個物件,將目標物件的內容複製過來而不是直接複製引用呢?
這裡先講一下淺複製,淺複製會建立一個新物件,新物件和原物件本身沒有任何關係,新物件和原物件不等,但是新物件的屬性和老物件相同。具體可以看如下區別:
如果屬性是基本型別(int,double,long,boolean等),複製的就是基本型別的值;
如果屬性是引用型別,複製的就是記憶體地址(即複製引用但不復制引用的物件) ,因此如果其中一個物件改變了這個地址,就會 影響到另一個物件。
如果用一張圖來描述一下淺複製,
如何實現淺複製呢?也很簡單,就是在需要複製的類上實現Cloneable介面並重寫其clone()方法。
@Overrideprotected Object clone() throws CloneNotSupportedException {
return super.clone();
}
在使用的時候直接呼叫類的clone()方法即可。具體案例如下:
class Father{
String name;
public Father(String name) {
this.name=name;
}
@Override
public String toString() {
return "Father{" +
"name='" + name + '\'' +
'}';
}
}class Son implements Cloneable {
int age;
String name;
Father father;
public Son(String name,int age) {
this.age=age;
this.name = name;
}
public Son(String name,int age, Father father) {
this.age=age;
this.name = name;
this.father = father;
}
@Override
public String toString() {
return "Son{" +
"age=" + age +
", name='" + name + '\'' +
", father=" + father +
'}';
}
@Override
protected Son clone() throws CloneNotSupportedException {
return (Son) super.clone();
}
}public class test {
public static void main(String[] args) throws CloneNotSupportedException {
Father f=new Father("bigFather");
Son s1 = new Son("son1",13);
s1.father=f;
Son s2 = s1.clone();
System.out.println(s1);
System.out.println(s2);
System.out.println("s1==s2:"+(s1 == s2));//不相等
System.out.println("s1.name==s2.name:"+(s1.name == s2.name));//相等
System.out.println();
//但是他們的Father father 和String name的引用一樣
s1.age=12;
s1.father.name="smallFather";//s1.father引用未變
s1.name="son222";//類似 s1.name=new String("son222") 引用發生變化
System.out.println("s1.Father==s2.Father:"+(s1.father == s2.father));//相等
System.out.println("s1.name==s2.name:"+(s1.name == s2.name));//不相等
System.out.println(s1);
System.out.println(s2);
}
}
執行結果為:
Son{age=13, name='son1', father=Father{name='bigFather'}}
Son{age=13, name='son1', father=Father{name='bigFather'}}
s1==s2:false
s1.name==s2.name:true//此時相等
s1.Father==s2.Father:true
s1.name==s2.name:false//修改引用後不等
Son{age=12, name='son222', father=Father{name='smallFather'}}
Son{age=13, name='son1', father=Father{name='smallFather'}}
不出意外,這種淺複製除了物件本身不同以外,各個零部件和關係和複製物件都是相同的,就好像雙胞胎一樣,是兩個人,但是其開始的樣貌、各種關係(父母親人)都是相同的。需要注意的是其中name初始==是相等的,是因為初始淺複製它們指向一個相同的String,而後s1.name="son222" 則改變引用指向。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69990088/viewspace-2755272/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java引用複製、淺複製、深複製Java
- 淺複製與深複製
- js 淺拷貝(淺複製、淺克隆)、深拷貝(深複製、深克隆)JS
- go的深複製跟淺複製Go
- Java 中的深複製和淺複製你瞭解嗎?Java
- python 的深淺複製Python
- python 淺複製、深複製坑Python
- python 深複製和淺複製Python
- JavaScript 淺複製和深複製JavaScript
- JavaScript中的淺複製與深複製JavaScript
- 淺談JS中物件的淺複製和深複製JS物件
- JS物件複製:深複製和淺複製JS物件
- Python列表的深淺複製Python
- go slice深複製和淺複製Go
- python深複製和淺複製的區別Python
- 淺複製和深複製的概念與值複製和指標複製(引用複製)有關 淺複製 “指標複製 深複製 值複製指標
- 25. 深淺複製
- 好好捋一捋類載入和垃圾回收
- [筆記]捋一捋iOS中的MVC設計模式筆記iOSMVC設計模式
- 淺複製、深複製與序列化【初級Java必需理解的概念】Java
- C#中的物件深複製和淺複製C#物件
- 詳談Javascript中的深複製和淺複製JavaScript
- Spring Boot 日誌各種使用姿勢,是時候捋清楚了!Spring Boot
- 重新捋一捋React原始碼之更新渲染流程React原始碼
- 淺顯直白的Python深複製與淺複製區別說明Python
- 深淺複製,溫故知新
- js 淺複製和深複製的區別和應用JS
- python 深/淺複製及其區別Python
- TLS、SSL、CA 證書、公鑰、私鑰。。。今天捋一捋!TLS
- 對於複製普通物件 深複製和淺複製是否一樣物件
- Day 7.5 資料型別總結 + 複製 淺複製 深複製資料型別
- 面試題分解—「淺複製/深複製、定義屬性使用copy還是strong ?」面試題
- 今天來捋一捋位元組跳動小程式的坑,受不了了
- 深入理解JavaScript之深淺複製JavaScript
- 資料共享(淺複製)與資料獨立(深複製)
- js 實現深複製/深複製JS
- Python中的賦值與淺複製與深複製之間的關係Python賦值
- 深複製