亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

java淺拷貝和深拷貝(基礎也是很重要的)

標簽:
Java

对象的copy你兴许只是懵懂,或者是并没在意,来了解下吧。

对于的github基础代码https://github.com/chywx/JavaSE

最近学习c++,跟java很是相像,在慕课网学习c++也算是重温习了下java基础

明白了当初讲师一直强调java传递的话只有值传递,不存在引用传递,为什么一直要重复这,既然只有值传递,为啥还强调不是引用传递

毛病啊这是

 学了c++才知道,原来c++有值传递,引用传递的说法,但是java只是值传递

最简单的理解就是对于方法调用

比如 f(int a,int b) 这是值传递,传递过来的值不会被修改。

再如 f(int &a,int &b)这是引用传递,传递过来的值会被修改

 

步入正轨,说一说java的浅拷贝(Shallow Copy)、深拷贝(Deep Copy)。

浅拷贝(Shallow Copy):①对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象。因为是两份不同的数据,所以对其中一个对象的该成员变量值进行修改,不会影响另一个对象拷贝得到的数据。②对于数据类型是引用数据类型的成员变量,比如说成员变量是某个数组、某个类的对象等,那么浅拷贝会进行引用传递,也就是只是将该成员变量的引用值(内存地址)复制一份给新的对象。因为实际上两个对象的该成员变量都指向同一个实例。在这种情况下,在一个对象中修改该成员变量会影响到另一个对象的该成员变量值。

通过示例来了解下,https://img1.sycdn.imooc.com//5b8bf154000114f102750082.jpg

 一:

  使用构造函数实现copy

复制代码

public class Person {    public static void main(String[] args) {
        Son s = new Son(10);
        Person p1 = new Person("大海", s);
        Person p2 = new Person(p1);
        p1.setSonName("小海");
        p1.getSon().setAge(12);
        System.out.println("p1:" + p1);// p1:Person [sonName=小海, son=Son [age=10]]
        System.out.println("p2:" + p2);// p2:Person [sonName=大海, son=Son [age=10]]
    }    private String sonName;    private Son son;    // 自定义拷贝函数
    public Person(Person person) {        this.sonName = person.sonName;        this.son = person.son;
    }    public Person(String sonName, Son son) {        super();        this.sonName = sonName;        this.son = son;
    }    public String getSonName() {        return sonName;
    }    public void setSonName(String sonName) {        this.sonName = sonName;
    }    public Son getSon() {        return son;
    }    public void setSon(Son son) {        this.son = son;
    }

    @Override    public String toString() {        return "Person [sonName=" + sonName + ", son=" + son + "]";
    }

}class Son {    private int age;    public int getAge() {        return age;
    }    public void setAge(int age) {        this.age = age;
    }    public Son(int age) {        super();        this.age = age;
    }

    @Override    public String toString() {        return "Son [age=" + age + "]";
    }

}

复制代码

结果

p1:Person [sonName=小海, son=Son [age=12]]
p2:Person [sonName=大海, son=Son [age=12]]

对于上面的实例,该person对象有两个成员,一个基本类型,一个引用类型,结果是拷贝出来的对象,基本类型的那个成员真正的实现了copy。

 二:

  使用自带的clone方法,需要实现cloneable接口,不然会

Exception in thread "main" java.lang.CloneNotSupportedException:

https://img1.sycdn.imooc.com//5b8bf15f0001054b04550075.jpg

https://img1.sycdn.imooc.com//5b8bf1640001c1da01780053.jpg 

复制代码

public class Person2 implements Cloneable {    public static void main(String[] args) throws CloneNotSupportedException {
        Son2 son1 = new Son2(10);

        Person2 person1 = new Person2("大海", son1);
        Person2 person2 = (Person2) person1.clone();
        person2.setSon2Name("小海");
        person2.getSon2().setAge(12);
        System.out.println(person1);
        System.out.println(person2);
    }    public Person2(String son2Name, Son2 son2) {        super();        this.son2Name = son2Name;        this.son2 = son2;
    }    private String son2Name;    private Son2 son2;    public String getSon2Name() {        return son2Name;
    }    public void setSon2Name(String son2Name) {        this.son2Name = son2Name;
    }    public Son2 getSon2() {        return son2;
    }    public void setSon2(Son2 son2) {        this.son2 = son2;
    }

    @Override    protected Object clone() throws CloneNotSupportedException {        return super.clone();
    }

    @Override    public String toString() {        return "Person2 [son2Name=" + son2Name + ", son2=" + son2 + "]";
    }

}class Son2 {    private int age;    public int getAge() {        return age;
    }    public void setAge(int age) {        this.age = age;
    }

    @Override    public String toString() {        return "Son2 [age=" + age + "]";
    }    public Son2(int age) {        super();        this.age = age;
    }

}

复制代码

 

 结果:

Person2 [son2Name=大海, son2=Son2 [age=12]]
Person2 [son2Name=小海, son2=Son2 [age=12]]

使用自带的copy实现浅拷贝

---------------------------------------------------------------------------------------------------

深拷贝

  相对于浅拷贝而言,对于引用类型的修改,并不会影响到对应的copy对象的值。每一层的每个对象都进行浅拷贝=深拷贝。

一:

  还是使用clone方法,只不过得手动重写一下。

https://img1.sycdn.imooc.com//5b8bf16b0001688f04790106.jpg

上代码

复制代码

public class Person3 implements Cloneable {    public static void main(String[] args) throws CloneNotSupportedException {
        Son3 son1 = new Son3(10);
        Person3 person1 = new Person3("大海", son1);
        Person3 person2 = (Person3) person1.clone();
        person2.setSon2Name("小海");
        person2.getSon3().setAge(12);//修改对应的引用对象的值。        System.out.println(person1);
        System.out.println(person2);
    }    public Person3(String son2Name, Son3 son3) {        super();        this.son2Name = son2Name;        this.son3 = son3;
    }    private String son2Name;    private Son3 son3;    public String getSon2Name() {        return son2Name;
    }    public void setSon2Name(String son2Name) {        this.son2Name = son2Name;
    }    public Son3 getSon3() {        return son3;
    }    public void setSon3(Son3 son3) {        this.son3 = son3;
    }

    @Override    protected Object clone() throws CloneNotSupportedException {
        Person3 clone = (Person3) super.clone();
        clone.setSon3((Son3) clone.getSon3().clone());        return clone;
    }

    @Override    public String toString() {        return "Person3 [son2Name=" + son2Name + ", son3=" + son3 + "]";
    }

}class Son3 implements Cloneable {    private int age;    public int getAge() {        return age;
    }    public void setAge(int age) {        this.age = age;
    }

    @Override    public String toString() {        return "Son2 [age=" + age + "]";
    }    public Son3(int age) {        super();        this.age = age;
    }

    @Override    protected Object clone() throws CloneNotSupportedException {        return super.clone();
    }

}

复制代码

 

结果:

Person3 [son2Name=大海, son3=Son2 [age=10]]

Person3 [son2Name=小海, son3=Son2 [age=12]]

方法二:

  显然对于多个对象的话,显然就很吃力。可以使用另一种方式,

  将对象序列化为字节序列后,默认会将该对象的整个对象图进行序列化,再通过反序列即可完美地实现深拷贝。

 https://img1.sycdn.imooc.com//5b8bf1730001647702600062.jpg

复制代码

public class Person4 implements Serializable {    public static void main(String[] args) throws CloneNotSupportedException, ClassNotFoundException, IOException {
        Son4 son = new Son4(10);
        Person4 person1 = new Person4("大海", son);        //通过序列化方法实现深拷贝
        ByteArrayOutputStream bos=new ByteArrayOutputStream();
        ObjectOutputStream oos=new ObjectOutputStream(bos);
        oos.writeObject(person1);
        oos.flush();
        ObjectInputStream ois=new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
        Person4 person2=(Person4)ois.readObject();
        person1.setSon4Name("小海");
        person1.getSon4().setAge(12);
        System.out.println(person1.toString());
        System.out.println(person2.toString());
    }    public Person4(String son4Name, Son4 son4) {        super();        this.son4Name = son4Name;        this.son4 = son4;
    }    private String son4Name;    private Son4 son4;    public String getSon4Name() {        return son4Name;
    }    public void setSon4Name(String son4Name) {        this.son4Name = son4Name;
    }    public Son4 getSon4() {        return son4;
    }    public void setSon4(Son4 son4) {        this.son4 = son4;
    }

    @Override    public String toString() {        return "Person4 [son4Name=" + son4Name + ", son4=" + son4 + "]";
    }
}class Son4 implements Serializable {    private int age;    public int getAge() {        return age;
    }    public void setAge(int age) {        this.age = age;
    }
    @Override    public String toString() {        return "Son2 [age=" + age + "]";
    }    public Son4(int age) {        super();        this.age = age;
    }

}

复制代码

这是实现序列化接口方案,nice. 

perfect!!!到位

 记录下听得歌曲。

复制代码

    绝世
            (张克帆)
世间种种的诱惑
不惊不扰我清梦
山高路远不绝我
追踪你绝美的笑容
登高一呼时才懂
始终在为你心痛
俯首对花影摇动
都是东风在捉弄
世间种种的迷惑
都是因你而猜错
水光月光又交融
描述这朗朗的夜空
生死到头的相从
似狂花落叶般从容
当一切泯灭如梦
就在远山被绝世尘封

复制代码

原文出处:https://www.cnblogs.com/c-h-y/p/9574586.html

點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消