<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【137期】面試官:?jiǎn)桙c(diǎn)兒基礎(chǔ)的,你能說說Java深拷貝和淺拷貝區(qū)別嗎

          共 5635字,需瀏覽 12分鐘

           ·

          2021-02-26 07:20

          程序員的成長(zhǎng)之路
          互聯(lián)網(wǎng)/程序員/技術(shù)/資料共享?
          關(guān)注


          閱讀本文大概需要 4 分鐘。

          作者:riemann
          blog.csdn.net/riemann_/article/details/87217229

          一、拷貝的引入

          (1)、引用拷貝

          創(chuàng)建一個(gè)指向?qū)ο蟮囊米兞康目截悺?/p>

          Teacher?teacher?=?new?Teacher("Taylor",26);
          Teacher?otherteacher?=?teacher;
          System.out.println(teacher);
          System.out.println(otherteacher);

          輸出結(jié)果:

          blog.Teacher@355da254
          blog.Teacher@355da254

          結(jié)果分析:由輸出結(jié)果可以看出,它們的地址值是相同的,那么它們肯定是同一個(gè)對(duì)象。teacher和otherteacher的只是引用而已,他們都指向了一個(gè)相同的對(duì)象Teacher(“Taylor”,26)。這就叫做引用拷貝。

          (2)、對(duì)象拷貝

          創(chuàng)建對(duì)象本身的一個(gè)副本。

          Teacher?teacher?=?new?Teacher("Swift",26);?
          Teacher?otherteacher?=?(Teacher)teacher.clone();?
          System.out.println(teacher);
          System.out.println(otherteacher);

          輸出結(jié)果:

          blog.Teacher@355da254
          blog.Teacher@4dc63996

          結(jié)果分析:由輸出結(jié)果可以看出,它們的地址是不同的,也就是說創(chuàng)建了新的對(duì)象, 而不是把原對(duì)象的地址賦給了一個(gè)新的引用變量,這就叫做對(duì)象拷貝。
          注:深拷貝和淺拷貝都是對(duì)象拷貝

          二、淺拷貝

          (1)、定義

          被復(fù)制對(duì)象的所有變量都含有與原來的對(duì)象相同的值,而所有的對(duì)其他對(duì)象的引用仍然指向原來的對(duì)象。即對(duì)象的淺拷貝會(huì)對(duì)“主”對(duì)象進(jìn)行拷貝,但不會(huì)復(fù)制主對(duì)象里面的對(duì)象。”里面的對(duì)象“會(huì)在原來的對(duì)象和它的副本之間共享。
          簡(jiǎn)而言之,淺拷貝僅僅復(fù)制所考慮的對(duì)象,而不復(fù)制它所引用的對(duì)象

          (2)、淺拷貝實(shí)例

          package?com.test;

          public?class?ShallowCopy?{
          ????public?static?void?main(String[]?args)?throws?CloneNotSupportedException?{
          ????????Teacher?teacher?=?new?Teacher();
          ????????teacher.setName("riemann");
          ????????teacher.setAge(27);

          ????????Student2?student1?=?new?Student2();
          ????????student1.setName("edgar");
          ????????student1.setAge(18);
          ????????student1.setTeacher(teacher);

          ????????Student2?student2?=?(Student2)?student1.clone();
          ????????System.out.println("拷貝后");
          ????????System.out.println(student2.getName());
          ????????System.out.println(student2.getAge());
          ????????System.out.println(student2.getTeacher().getName());
          ????????System.out.println(student2.getTeacher().getAge());

          ????????System.out.println("修改老師的信息后-------------");
          ????????//?修改老師的信息
          ????????teacher.setName("Games");
          ????????System.out.println(student1.getTeacher().getName());
          ????????System.out.println(student2.getTeacher().getName());

          ????}
          }

          class?Teacher?implements?Cloneable?{
          ????private?String?name;
          ????private?int?age;

          ????public?String?getName()?{
          ????????return?name;
          ????}

          ????public?void?setName(String?name)?{
          ????????this.name?=?name;
          ????}

          ????public?int?getAge()?{
          ????????return?age;
          ????}

          ????public?void?setAge(int?age)?{
          ????????this.age?=?age;
          ????}
          }

          class?Student2?implements?Cloneable?{
          ????private?String?name;
          ????private?int?age;
          ????private?Teacher?teacher;

          ????public?String?getName()?{
          ????????return?name;
          ????}

          ????public?void?setName(String?name)?{
          ????????this.name?=?name;
          ????}

          ????public?int?getAge()?{
          ????????return?age;
          ????}

          ????public?void?setAge(int?age)?{
          ????????this.age?=?age;
          ????}

          ????public?Teacher?getTeacher()?{
          ????????return?teacher;
          ????}

          ????public?void?setTeacher(Teacher?teacher)?{
          ????????this.teacher?=?teacher;
          ????}

          ????public?Object?clone()?throws?CloneNotSupportedException?{
          ????????Object?object?=?super.clone();
          ????????return?object;
          ????}
          }

          輸出結(jié)果:

          拷貝后
          edgar
          18
          riemann
          27
          修改老師的信息后-------------
          Games
          Games

          結(jié)果分析:兩個(gè)引用student1和student2指向不同的兩個(gè)對(duì)象,但是兩個(gè)引用student1和student2中的兩個(gè)teacher引用指向的是同一個(gè)對(duì)象,所以說明是淺拷貝。

          三、深拷貝

          (1)、定義

          深拷貝是一個(gè)整個(gè)獨(dú)立的對(duì)象拷貝,深拷貝會(huì)拷貝所有的屬性,并拷貝屬性指向的動(dòng)態(tài)分配的內(nèi)存。當(dāng)對(duì)象和它所引用的對(duì)象一起拷貝時(shí)即發(fā)生深拷貝。深拷貝相比于淺拷貝速度較慢并且花銷較大。
          簡(jiǎn)而言之,深拷貝把要復(fù)制的對(duì)象所引用的對(duì)象都復(fù)制了一遍。

          (2)、深拷貝實(shí)例

          package?com.test;

          public?class?DeepCopy?{
          ????public?static?void?main(String[]?args)?throws?CloneNotSupportedException?{
          ????????Teacher2?teacher?=?new?Teacher2();
          ????????teacher.setName("riemann");
          ????????teacher.setAge(27);

          ????????Student3?student1?=?new?Student3();
          ????????student1.setName("edgar");
          ????????student1.setAge(18);
          ????????student1.setTeacher(teacher);

          ????????Student3?student2?=?(Student3)?student1.clone();
          ????????System.out.println("拷貝后");
          ????????System.out.println(student2.getName());
          ????????System.out.println(student2.getAge());
          ????????System.out.println(student2.getTeacher().getName());
          ????????System.out.println(student2.getTeacher().getAge());

          ????????System.out.println("修改老師的信息后-------------");
          ????????//?修改老師的信息
          ????????teacher.setName("Games");
          ????????System.out.println(student1.getTeacher().getName());
          ????????System.out.println(student2.getTeacher().getName());
          ????}
          }

          class?Teacher2?implements?Cloneable?{
          ????private?String?name;
          ????private?int?age;

          ????public?String?getName()?{
          ????????return?name;
          ????}

          ????public?void?setName(String?name)?{
          ????????this.name?=?name;
          ????}

          ????public?int?getAge()?{
          ????????return?age;
          ????}

          ????public?void?setAge(int?age)?{
          ????????this.age?=?age;
          ????}

          ????public?Object?clone()?throws?CloneNotSupportedException?{
          ????????return?super.clone();
          ????}
          }

          class?Student3?implements?Cloneable?{
          ????private?String?name;
          ????private?int?age;
          ????private?Teacher2?teacher;

          ????public?String?getName()?{
          ????????return?name;
          ????}

          ????public?void?setName(String?name)?{
          ????????this.name?=?name;
          ????}

          ????public?int?getAge()?{
          ????????return?age;
          ????}

          ????public?void?setAge(int?age)?{
          ????????this.age?=?age;
          ????}

          ????public?Teacher2?getTeacher()?{
          ????????return?teacher;
          ????}

          ????public?void?setTeacher(Teacher2?teacher)?{
          ????????this.teacher?=?teacher;
          ????}

          ????public?Object?clone()?throws?CloneNotSupportedException?{
          ????????//?淺復(fù)制時(shí):
          ????????//?Object?object?=?super.clone();
          ????????//?return?object;

          ????????//?改為深復(fù)制:
          ????????Student3?student?=?(Student3)?super.clone();
          ????????//?本來是淺復(fù)制,現(xiàn)在將Teacher對(duì)象復(fù)制一份并重新set進(jìn)來
          ????????student.setTeacher((Teacher2)?student.getTeacher().clone());
          ????????return?student;

          ????}
          }

          輸出結(jié)果:

          拷貝后
          edgar
          18
          riemann
          27
          修改老師的信息后-------------
          Games
          riemann

          結(jié)果分析:
          兩個(gè)引用student1和student2指向不同的兩個(gè)對(duì)象,兩個(gè)引用student1和student2中的兩個(gè)teacher引用指向的是兩個(gè)對(duì)象,但對(duì)teacher對(duì)象的修改只能影響student1對(duì)象,所以說是深拷貝。

          推薦閱讀:

          【136期】你能談?wù)凧ava中 synchronized 對(duì)象鎖和類鎖的區(qū)別

          【135期】談?wù)凪ySQL中的重做日志,回滾日志,以及二進(jìn)制日志的區(qū)別及各自作用

          【134期】面試官:你知道 Redis 內(nèi)部是怎么實(shí)現(xiàn)它的字符串的么?

          5T技術(shù)資源大放送!包括但不限于:C/C++,Linux,Python,Java,PHP,人工智能,單片機(jī),樹莓派,等等。在公眾號(hào)內(nèi)回復(fù)「2048」,即可免費(fèi)獲取!!

          微信掃描二維碼,關(guān)注我的公眾號(hào)

          朕已閱?

          瀏覽 46
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美aaa国产aaa亚洲aaa免费看 | 亚洲视频中文字幕在线观看 | 婷婷亚洲综合五月天小说 | 日韩欧美纯爱电影片在线观看 | 爽灬爽灬无码无遮挡在线看 |