最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java 深拷貝與淺拷貝的分析

 更新時(shí)間:2016年07月20日 11:25:14   投稿:lqh  
本文主要介紹java 的深拷貝和淺拷貝,這里通過實(shí)例代碼對深拷貝和淺拷貝做了詳細(xì)的比較,希望能幫到有需要的小伙伴

在正式的進(jìn)入主題之前,我們先來了解下深拷貝和前拷貝的概念:

淺拷貝:

會(huì)創(chuàng)建一個(gè)新對象,這個(gè)對象有著原始對象屬性值的一份精確拷貝,如果屬性是基本類型,拷貝的是基本類型的值;如果屬性是內(nèi)存地址,拷貝的就是內(nèi)存地址,因此如果一個(gè)對象改變了這個(gè)地址就會(huì)影響到另一個(gè)對象;

深拷貝:

不僅要復(fù)制對象的所有非引用成員變量值,還要為引用類型的成員變量創(chuàng)建新的實(shí)例,并且初始化為形式參數(shù)實(shí)例值;

了解完概念之后,我們來測試下普通的對象賦值操作屬于深拷貝還是淺拷貝:

測試代碼:

public class DepthCopy { 
  public static void main(String[] args) { 
    Copy first = new Copy("hzw", 24); 
    Copy second = first; 
    second.name = "shanxi"; 
    System.out.println(first.name);//輸出shanxi 
  } 
} 
class Copy 
{ 
  public String name; 
  public int age; 
  public Copy(String name,int age) { 
    this.name = name; 
    this.age = age; 
  } 
} 

可以發(fā)現(xiàn),在second將name屬性值修改為shanxi之后,first的name屬性值也變成了shanxi,這點(diǎn)就可以看出普通的對象賦值屬于淺拷貝;

明白了對象之間賦值是淺拷貝之后,接下來我們來看看克隆到底是深拷貝還是淺拷貝,測試代碼是讓上面的Copy對象實(shí)現(xiàn)Cloneable接口里面的clone方法:

public class DepthCopy { 
  public static void main(String[] args) { 
    Copy first = new Copy("hzw", 24); 
    Copy second = null; 
    try { 
      second = (Copy) first.clone(); 
    } catch (CloneNotSupportedException e) { 
      e.printStackTrace(); 
    } 
    second.name = "shanxi"; 
    System.out.println(first.name);//輸出: hzw 
    System.out.println(first);//輸出: com.hzw.day33.Copy@7f39ebdb 
    System.out.println(second);//輸出: com.hzw.day33.Copy@33abb81e 
  } 
} 
class Copy implements Cloneable 
{ 
  public String name; 
  public int age; 
  public Copy(String name,int age) { 
    this.name = name; 
    this.age = age; 
  } 
  @Override 
  protected Object clone() throws CloneNotSupportedException { 
    return super.clone(); 
  } 
} 

可以看出原先創(chuàng)建出的對象first和克隆創(chuàng)建出的對象second是兩個(gè)實(shí)例,因此對于second中name屬性的修改并不會(huì)影響first中的name屬性;但是,我們并不能單純的認(rèn)為克隆就是深拷貝的,比如下面這個(gè)例子:

public class DepthCopy { 
  public static void main(String[] args) { 
    Student student = new Student(95); 
    Copy first = new Copy("hzw", 24,student); 
    Copy second = null; 
    try { 
      second = (Copy) first.clone(); 
    } catch (CloneNotSupportedException e) { 
      e.printStackTrace(); 
    } 
    second.name = "shanxi"; 
    second.student.score = 60; 
    System.out.println(first == second);//false 
    System.out.println(first.student == second.student);//true 
    System.out.println(first.student.score);//60 
  } 
} 
class Copy implements Cloneable 
{ 
  public String name; 
  public int age; 
  public Student student; 
  public Copy(String name,int age,Student student) { 
    this.name = name; 
    this.age = age; 
    this.student = student; 
  } 
  @Override 
  protected Object clone() throws CloneNotSupportedException { 
    return super.clone(); 
  } 
} 
class Student  
{ 
  public int score; 
  public Student(int score) { 
    this.score = score; 
  } 
} 

看到?jīng)]有呢?我們通過克隆的方式創(chuàng)建了second,很明顯發(fā)現(xiàn)first和second是兩個(gè)實(shí)例,因?yàn)閒irst == second輸出為false,但是first和second里面的student對象卻是一樣的,通過second修改了student的score值之后,first里面student的score也發(fā)生了改變,這也就是說first和second里面的student是相同的,這也就說明了克隆是淺拷貝的,我們要想實(shí)現(xiàn)克隆的深拷貝,必須讓Copy對象里面的Student對象也要實(shí)現(xiàn)Cloneable接口里面的clone方法,并且在Copy里面的克隆方法返回Student的一個(gè)克隆即可,這樣就可以保證Student的唯一啦,修改之后的代碼如下:

public class DepthCopy { 
  public static void main(String[] args) { 
    Student student = new Student(95); 
    Copy first = new Copy("hzw", 24,student); 
    Copy second = null; 
    try { 
      second = (Copy) first.clone(); 
    } catch (CloneNotSupportedException e) { 
      e.printStackTrace(); 
    } 
    second.name = "shanxi"; 
    second.student.score = 60; 
    System.out.println(first == second);//false 
    System.out.println(first.student == second.student);//false 
    System.out.println(first.student.score);//95 
    System.out.println(second.student.score);//60 
  } 
} 
class Copy implements Cloneable 
{ 
  public String name; 
  public int age; 
  public Student student; 
  public Copy(String name,int age,Student student) { 
    this.name = name; 
    this.age = age; 
    this.student = student; 
  } 
  @Override 
  protected Object clone() throws CloneNotSupportedException { 
    Copy copy = (Copy)super.clone(); 
    copy.student = (Student) student.clone(); 
    return copy; 
  } 
} 
class Student implements Cloneable 
{ 
  public int score; 
  public Student(int score) { 
    this.score = score; 
  } 
  @Override 
  protected Object clone() throws CloneNotSupportedException { 
    return super.clone(); 
  } 
} 

可以看到此時(shí)first和second和first.student和second.student都不是相同的,因此我們修改second的student的score之后并沒有影響到first里的student的score值,達(dá)到了深拷貝的目的;

但是,仔細(xì)一想問題就出來了,假如我們上面例子的Student類中也存在引用類型的屬性,比如College類,那么我們必須讓College類實(shí)現(xiàn)Cloneable接口,然后在Student類里面的clone方法里面調(diào)用College類的clone方法,在Copy類的clone方法中調(diào)用Student類的clone方法,發(fā)現(xiàn)沒有了,這個(gè)過程好復(fù)雜,必須讓類中的有關(guān)引用類型全部實(shí)現(xiàn)Cloneable接口,感覺好麻煩是不是,好的,接下來就該牛人登場了;

解決深拷貝問題最好的方式就是采用序列化方式,這樣各種類均不用實(shí)現(xiàn)Cloneable接口的,直接序列化反序列化就可以啦,我們來見識下吧。

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.io.Serializable; 
 
public class DepthCopy { 
  public static void main(String[] args) { 
    College school = new College("nongda"); 
    Student student = new Student(95, school); 
    Copy copy = new Copy("hzw",23, student); 
    Copy another = null;//表示反序列化出來的類實(shí)例 
    //進(jìn)行序列化操作 
    try { 
      FileOutputStream fos = new FileOutputStream(new File("d:/copy.txt")); 
      ObjectOutputStream oos = new ObjectOutputStream(fos); 
      oos.writeObject(copy); 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
    //進(jìn)行反序列化操作 
    FileInputStream fis; 
    try { 
      fis = new FileInputStream(new File("d:/copy.txt")); 
      ObjectInputStream ois = new ObjectInputStream(fis); 
      another = (Copy) ois.readObject(); 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
    System.out.println(copy == another);//false 
    System.out.println(copy.student == another.student);//false 
    System.out.println(copy.student.school == another.student.school);//false 
    another.student.school.schoolName = "wuda"; 
    System.out.println(copy.student.school.schoolName);//nongda 
  } 
} 
class Copy implements Serializable 
{ 
  public String name; 
  public int age; 
  public Student student; 
  public Copy(String name,int age,Student student) { 
    this.name = name; 
    this.age = age; 
    this.student = student; 
  } 
} 
class Student implements Serializable 
{ 
  public int score; 
  public College school; 
  public Student(int score,College school) { 
    this.score = score; 
    this.school = school; 
  } 
} 
class College implements Serializable 
{ 
  public String schoolName; 
  public College(String schoolName) { 
    this.schoolName = schoolName; 
  } 
} 

從輸出就可以看出來,反序列化之后生成的對象完全就是對原對象的一份拷貝,除了屬性值相同之外并不和原對象有任何關(guān)系,因此當(dāng)我們修改反序列化生成對象的schoolName為"wuda"的時(shí)候并沒有修改原來實(shí)例的schoolName值,還是輸出"nongda",因此達(dá)到了真正的深拷貝效果,但是要想實(shí)現(xiàn)序列化,所有的有關(guān)類都必須實(shí)現(xiàn)Serializable接口,這總也比既實(shí)現(xiàn)Cloneable接口又實(shí)現(xiàn)clone方法更方便吧。

以上就是對Java 深拷貝和淺拷貝的詳細(xì)講解,有需要的可以參考下。

相關(guān)文章

  • spring-boot2.7.8添加swagger的案例詳解

    spring-boot2.7.8添加swagger的案例詳解

    這篇文章主要介紹了spring-boot2.7.8添加swagger的案例詳解,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-01-01
  • 淺談Java自動(dòng)裝箱與拆箱及其陷阱

    淺談Java自動(dòng)裝箱與拆箱及其陷阱

    下面小編就為大家?guī)硪黄獪\談Java自動(dòng)裝箱與拆箱及其陷阱。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-06-06
  • SpringBoot中的@Value注解用法

    SpringBoot中的@Value注解用法

    這篇文章主要介紹了SpringBoot中的@Value注解用法,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Selenium處理select標(biāo)簽的下拉框

    Selenium處理select標(biāo)簽的下拉框

    Selenium是一個(gè)開源的和便攜式的自動(dòng)化軟件測試工具,用于測試Web應(yīng)用程序有能力在不同的瀏覽器和操作系統(tǒng)運(yùn)行。接下來通過本文給大家介紹Selenium處理select標(biāo)簽的下拉框,需要的朋友一起學(xué)習(xí)吧
    2016-04-04
  • spring AOP代理執(zhí)行@EnableAspectJAutoProxy的exposeProxy屬性詳解

    spring AOP代理執(zhí)行@EnableAspectJAutoProxy的exposeProxy屬性詳解

    這篇文章主要為大家介紹了spring AOP代理執(zhí)行@EnableAspectJAutoProxy的exposeProxy屬性詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • java高效實(shí)現(xiàn)大文件拷貝功能

    java高效實(shí)現(xiàn)大文件拷貝功能

    這篇文章主要為大家詳細(xì)介紹了java高效實(shí)現(xiàn)大文件拷貝功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • SpringMVC 異常處理機(jī)制與自定義異常處理方式

    SpringMVC 異常處理機(jī)制與自定義異常處理方式

    這篇文章主要介紹了SpringMVC 異常處理機(jī)制與自定義異常處理方式,具有很好的開車價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java:com.netflix.client.ClientException錯(cuò)誤解決

    Java:com.netflix.client.ClientException錯(cuò)誤解決

    本文主要介紹了Java:com.netflix.client.ClientException錯(cuò)誤解決,主要是指出客戶端?module-sso?試圖通過負(fù)載均衡器訪問服務(wù)時(shí),負(fù)載均衡器沒有找到可用的服務(wù)器來處理請求,下面就來介紹一下解決方法
    2024-08-08
  • SpringMVC中請求參數(shù)的獲取方式

    SpringMVC中請求參數(shù)的獲取方式

    這篇文章主要為大家介紹了SpringMVC中請求參數(shù)的獲取方式,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • Jmail發(fā)送郵件工具類分享

    Jmail發(fā)送郵件工具類分享

    這篇文章主要為大家分享了Jmail發(fā)送郵件工具類,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06

最新評論

罗田县| 无极县| 光泽县| 辽源市| 郑州市| 虞城县| 梁河县| 涞水县| 五寨县| 清原| 吴江市| 乌拉特前旗| 洛川县| 承德县| 九龙城区| 扎鲁特旗| 农安县| 延川县| 天柱县| 府谷县| 大理市| 秭归县| 济阳县| 丽水市| 呼和浩特市| 台东市| 肃北| 彰化县| 平江县| 比如县| 昌乐县| 昆明市| 沽源县| 祁阳县| 大同县| 政和县| 虹口区| 夹江县| 湟中县| 巴中市| 黄大仙区|