Java 深copy 浅copy 引用copy
生活随笔
收集整理的這篇文章主要介紹了
Java 深copy 浅copy 引用copy
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
大家好,我是烤鴨:
? ? 今天分享一下淺copy和深copy。
?
1.? ?深copy
? ? 什么是深copy,只復制原對象屬性值,不管地址。
? ? 說一下業(yè)務場景:
? ? 如果我想創(chuàng)建一個對象,只是對原對象的某個屬性值改變。普通的做法就是new 一個對象,然后setXXX,如果屬性特別多的話不方便,這時候就是需要深copy。復制出來的對象屬于不同的地址,改變復制對象的屬性值不會影響原對象。
? ? TestClone.java:
package com.xxx.xxx.utils;import org.junit.Test;import java.io.Serializable;/*** Created by on 2018/7/23*/ public class TestClone {public TestClone() {}@Testpublic void testDeepCopy(){Person person1 = new Person();person1.id = "id1";person1.name = "name1";person1.sex = "sex1";System.out.println("復制前person:"+person1);Person clone = CloneUtils.clone(person1);System.out.println("這是深copy后的對象:"+clone);System.out.println("=========改變深copy后的對象屬性=====================");clone.id = "id2";clone.name = "name2";clone.sex = "sex2";System.out.println("copy的對象:"+clone);System.out.println("復制后person:"+person1);}} class Person implements Serializable,Cloneable{String id;String name;String sex;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}@Overridepublic String toString() {return "Person{" +"id='" + id + '\'' +", name='" + name + '\'' +", sex='" + sex + '\'' +'}';}@Overridepublic Person clone() {Person person = null;try {person = (Person) super.clone();} catch (CloneNotSupportedException ignored) {System.out.println(ignored.getMessage());}return person;} }CloneUtils.java:
package com.xxx.xxx.utils;import java.io.*;public class CloneUtils {@SuppressWarnings("unchecked")public static <T extends Serializable> T clone(T obj){T cloneObj = null;try {//寫入字節(jié)流ByteArrayOutputStream out = new ByteArrayOutputStream();ObjectOutputStream obs = new ObjectOutputStream(out);obs.writeObject(obj);obs.close();//分配內(nèi)存,寫入原始對象,生成新對象ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray());ObjectInputStream ois = new ObjectInputStream(ios);//返回生成的新對象cloneObj = (T) ois.readObject();ois.close();} catch (Exception e) {e.printStackTrace();}return cloneObj;} }結果如圖:
?
2.? ?淺copy
? ? 與深copy相對應,淺copy就是復制的對象指向了原對象的地址值。如果復制的對象屬性值改變,原對象也會隨之改變。
? ? 如果是單個對象的話,用引用copy吧。
? ? 如果是對象中還有屬性是對象的話。
? ? Person.java 和 Man.java
? ??
class Person implements Cloneable, Serializable {String id;String name;String sex;Man man;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public Man getMan() {return man;}public void setMan(Man man) {this.man = man;}@Overridepublic String toString() {return "Person{" +"id='" + id + '\'' +", name='" + name + '\'' +", sex='" + sex + '\'' +", man=" + man +'}';}@Overridepublic Person clone() {Person person = null;try {person = (Person) super.clone();} catch (CloneNotSupportedException ignored) {System.out.println(ignored.getMessage());}return person;} } class Man{String name;String age;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}@Overridepublic String toString() {return "Man{" +"name='" + name + '\'' +", age='" + age + '\'' +'}';} } /*** 淺復制* @throws IOException* @throws ClassNotFoundException*/@Testpublic void testShallowCopy() throws IOException, ClassNotFoundException {Person person1 = new Person();Man man = new Man();man.name = "man1";man.age = "age1";person1.id = "id1";person1.name = "name1";person1.sex = "sex1";person1.man = man;System.out.println("復制前person:"+person1);Person clone = person1.clone();System.out.println("這是淺copy后的對象:"+clone);System.out.println("=========改變淺copy后的對象屬性=====================");clone.id = "id2";clone.name = "name2";clone.sex = "sex2";clone.man.name = "man2";clone.man.age = "age2";System.out.println("copy的對象:"+clone);System.out.println("復制后person:"+person1);}如圖:
可以看出,改變了man的屬性,原對象中的man屬性值也改變了。這就是淺copy。
如果不想這樣的話,就把man也clone。
man實現(xiàn)clone接口,重寫clone方法:
class Man implements Cloneable{String name;String age;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}@Overridepublic String toString() {return "Man{" +"name='" + name + '\'' +", age='" + age + '\'' +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();} }修改copy方法:
Man man2 = (Man) person1.man.clone();man2.name = "man2";man2.age = "age2";clone.man = man2;如圖:
3.? ? 引用copy
/*** 引用復制* @throws IOException* @throws ClassNotFoundException*/@Testpublic void testQuoteCopy() throws IOException, ClassNotFoundException {Person person1 = new Person();person1.id = "id1";person1.name = "name1";person1.sex = "sex1";System.out.println("復制前person:"+person1);Person clone = person1;System.out.println("這是引用copy后的對象:"+clone);System.out.println("=========改變引用copy后的對象屬性=====================");clone.id = "id2";clone.name = "name2";clone.sex = "sex2";System.out.println("copy的對象:"+clone);System.out.println("復制后person:"+person1);}如圖:
? ?
總結
以上是生活随笔為你收集整理的Java 深copy 浅copy 引用copy的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaScript this 关键字
- 下一篇: 基于Unity引擎的RPG3D项目开发笔