<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
參照拷貝: 參照拷貝不會在堆上建立一個新的物件,只 會在棧上生成一個新的參照地址,最終指向依然是堆上的同一個物件。
//實體類 public class Person{ public String name;//姓名 public int height;//身高 public StringBuilder something; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public StringBuilder getSomething() { return something; } public void setSomething(StringBuilder something) { this.something = something; } public Person(String name, int height, StringBuilder something) { this.name = name; this.height = height; this.something = something; } } //測試類 public class copyTest { public static void main(String[] args) { Person p1 = new Person("小張", 180, new StringBuilder("今天天氣很好")); Person p2 = p1; System.out.println("物件是否相等:"+ (p1 == p2)); System.out.println("p1 屬性值=" + p1.getName()+ ","+ p1.getHeight() + ","+ p1.getSomething()); System.out.println("p2 屬性值=" + p2.getName()+ ","+ p2.getHeight() + ","+ p2.getSomething()); // change p1.name="小王"; p1.height = 200; p1.something.append(",適合出去玩"); System.out.println("...after p1 change...."); System.out.println("p1 屬性值=" + p1.getName()+ ","+ p1.getHeight() + ","+ p1.getSomething()); System.out.println("p2 屬性值=" + p2.getName()+ ","+ p2.getHeight() + ","+ p2.getSomething()); } }
結果:
物件是否相等:true
p1 屬性值=小張,180,今天天氣很好
p2 屬性值=小張,180,今天天氣很好
...after p1 change....
p1 屬性值=小王,200,今天天氣很好,適合出去玩
p2 屬性值=小王,200,今天天氣很好,適合出去玩
before change:
after change:
我們可以看出 由於2個參照p1,p2 都是指向堆中同一個物件,所以2個物件是相等的,修改了物件p1,會影響到物件p2
需要注意的
int weight=180;
是成員變數,存放在堆中,不是所有的基本型別變數 都存放在JVM棧中注意與這篇文章得區分開來, int num1 = 10;
是基本型別的區域性變數,存放在棧中
淺拷貝 :淺拷貝會在堆上建立一個新的物件,新物件和原物件不等,但是新物件的屬性和老物件相同。
其中:
如何實現淺拷貝呢?也很簡單,就是在需要拷貝的類上實現Cloneable介面並重寫其clone()方法。
@Override protected Object clone() throws CloneNotSupportedException { return super.clone(); }
在使用的時候直接呼叫類的clone()方法即可
//實體類 繼承Cloneable public class Person implements Cloneable{ public String name;//姓名 public int height;//身高 public StringBuilder something; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public StringBuilder getSomething() { return something; } public void setSomething(StringBuilder something) { this.something = something; } public Person(String name, int height, StringBuilder something) { this.name = name; this.height = height; this.something = something; } @Override public Person clone() throws CloneNotSupportedException { return (Person) super.clone(); } } //測試類 public class shallowCopyTest { public static void main(String[] args) throws CloneNotSupportedException { Person p1 = new Person("小張", 180, new StringBuilder("今天天氣很好")); Person p2 = p1.clone(); System.out.println("物件是否相等:"+ (p1 == p2)); System.out.println("p1 屬性值=" + p1.getName()+ ","+ p1.getHeight() + ","+ p1.getSomething()); System.out.println("p2 屬性值=" + p2.getName()+ ","+ p2.getHeight() + ","+ p2.getSomething()); // change p1.setName("小王"); p1.setHeight(200); p1.getSomething().append(",適合出去玩"); System.out.println("...after p1 change...."); System.out.println("p1 屬性值=" + p1.getName()+ ","+ p1.getHeight() + ","+ p1.getSomething()); System.out.println("p2 屬性值=" + p2.getName()+ ","+ p2.getHeight() + ","+ p2.getSomething()); } }
結果:
物件是否相等:false
p1 屬性值=小張,180,今天天氣很好
p2 屬性值=小張,180,今天天氣很好
...after p1 change....
p1 屬性值=小王,200,今天天氣很好,適合出去玩
p2 屬性值=小張,180,今天天氣很好,適合出去玩
before change:
after change:
我們可以看出:
深拷貝 :完全拷貝⼀個物件,在堆上建立一個新的物件,拷貝被拷貝物件的成員變數的值,同時堆中的物件也會拷貝。
需要重寫clone方法
@Override public Person clone() throws CloneNotSupportedException { //return (Person) super.clone(); Person person = (Person) super.clone(); person.setSomething( new StringBuilder(person.getSomething()));//單獨為參照型別clone return person; }
shallowCopyTest測試類的結果:
物件是否相等:false
p1 屬性值=小張,180,今天天氣很好
p2 屬性值=小張,180,今天天氣很好
...after p1 change....
p1 屬性值=小王,200,今天天氣很好,適合出去玩
p2 屬性值=小張,180,今天天氣很好
這時候物件p1和物件p2互不干擾了
before change:
after change:
但這樣也有個小問題,物件每有一個參照型別,我們都得重寫其clone方法,這樣會非常麻煩,因此我們還可以藉助序列化來實現物件的深拷貝
//實體類 繼承Cloneable public class Person implements Serializable{ public String name;//姓名 public int height;//身高 public StringBuilder something; ...//省略 getter setter public Object deepClone() throws Exception{ // 序列化 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); // 反序列化 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return ois.readObject(); } } //測試類,這邊類名筆者就不換了,在之前的基礎上改改 public class shallowCopyTest { public static void main(String[] args) throws Exception { Person p1 = new Person("小張", 180, new StringBuilder("今天天氣很好")); Person p2 = (Person)p1.deepClone(); System.out.println("物件是否相等:"+ (p1 == p2)); System.out.println("p1 屬性值=" + p1.getName()+ ","+ p1.getHeight() + ","+ p1.getSomething()); System.out.println("p2 屬性值=" + p2.getName()+ ","+ p2.getHeight() + ","+ p2.getSomething()); // change p1.setName("小王"); p1.setHeight(200); p1.getSomething().append(",適合出去玩"); System.out.println("...after p1 change...."); System.out.println("p1 屬性值=" + p1.getName()+ ","+ p1.getHeight() + ","+ p1.getSomething()); System.out.println("p2 屬性值=" + p2.getName()+ ","+ p2.getHeight() + ","+ p2.getSomething()); } }
這樣也會得到深拷貝的結果
參照拷貝: 參照拷貝不會在堆上建立一個新的物件,只 會在棧上生成一個新的參照地址,最終指向依然是堆上的同一個物件。
淺拷貝 :淺拷貝會在堆上建立一個新的物件,新物件和原物件不等,但是新物件的屬性和老物件相同。
其中:
如果屬性是基本型別(int,double,long,boolean等),拷貝的就是基本型別的值。
如果屬性是參照型別(除了基本型別都是參照型別),拷貝的就是引⽤資料型別變數的地址值,⽽對於引⽤型別變數指向的堆中的物件不會拷貝。
深拷貝 :完全拷貝⼀個物件,在堆上建立一個新的物件,拷貝被拷貝物件的成員變數的值,同時堆中的物件也會拷貝。
以上就是Java中深拷貝,淺拷貝與參照拷貝的區別詳解的詳細內容,更多關於Java拷貝的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45