深拷贝、浅拷贝

来源:互联网 发布:鸟哥的linux 编辑:程序博客网 时间:2024/06/06 04:25

把java对象的引用复制给另外一个对象,方法有三个:1.直接赋值、2.浅拷贝、3.深拷贝

1.直接赋值
实际上,直接赋值,是对象引用的复制,即这两个引用是指向同一个内存地址。A a2=a1,引用a1和a2是指向同一个对象,当修改任何一个引用时,都是修改同一个对象。

public class Student {    private String name;    private int age;    private String sex;    public Student(String name,int age,String sex){        this.name=name;        this.age=age;        this.sex=sex;    }    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 int getAge(){        return age;    }    public void setAge(int age){this.age=age;}}class MainTest{    public static void main(String[] args){        Student student=new Student("小晴 ",15,"男");        System.out.println("姓名:"+student.getName()+"  年龄:"+student.getAge()+"   性别:"+student.getSex());        Student student1=student;        student1.setAge(100);        System.out.println("姓名:"+student1.getName()+"  年龄:"+student1.getAge()+"   性别:"+student1.getSex());    }}

输出:

姓名:小晴   年龄:15   性别:男姓名:小晴   年龄:100   性别:男

可见两个引用实际指向同一个对象。

2.浅拷贝

如果想要两个引用相互独立,互不影响,我们可以利用Object 的clone()方法。而浅拷贝是指,如果是对象的非静态普通成员变量(值变量),则直接复制;如果是非静态类对象(引用类型),则复制引用但不复制引用的对象。

//对象内成员都是值变量public class Student implements Cloneable{    private String name;    private int age;    private String sex;    public Student(String name,int age,String sex){        this.name=name;        this.age=age;        this.sex=sex;    }    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 int getAge(){        return age;    }    public void setAge(int age){this.age=age;}    public Object clone(){        try {            return (Student)super.clone();        } catch (CloneNotSupportedException e) {            e.printStackTrace();            return null;        }    }}class MainTest{    public static void main(String[] args){        Student student=new Student("小晴 ",15,"男");        System.out.println("姓名:"+student.getName()+"  年龄:"+student.getAge()+"   性别:"+student.getSex());        Student student1=(Student) student.clone();        student1.setAge(100);        System.out.println("姓名:"+student1.getName()+"  年龄:"+student1.getAge()+"   性别:"+student1.getSex());        System.out.println("姓名:"+student.getName()+"  年龄:"+student.getAge()+"   性别:"+student.getSex());    }}姓名:小晴   年龄:15   性别:男姓名:小晴   年龄:100   性别:男姓名:小晴   年龄:15   性别:男
//成员有个类类型引用变量public class Student implements Cloneable{    private String name;    private int age;    private String sex;    private Mother mother;    public Student(String name,int age,String sex){        this.name=name;        this.age=age;        this.sex=sex;        this.mother=new Mother();    }    public Mother getMother() {        return mother;    }    public void setMother(String name){mother.setName(name);}    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 int getAge(){        return age;    }    public void setAge(int age){this.age=age;}    public Object clone(){        try {            return (Student)super.clone();        } catch (CloneNotSupportedException e) {            e.printStackTrace();            return null;        }    }}class MainTest{    public static void main(String[] args){        Student student=new Student("小晴 ",15,"男");        student.setMother("andy");        System.out.println("姓名:"+student.getName()+"  年龄:"+student.getAge()+"   性别:"+student.getSex()+"   mother:"+student.getMother().toString());        Student student1=(Student) student.clone();        student1.setAge(100);        student1.setMother("alice");        System.out.println("姓名:"+student1.getName()+"  年龄:"+student1.getAge()+"   性别:"+student1.getSex()+"   mother:"+student1.getMother().toString());        System.out.println("姓名:"+student.getName()+"  年龄:"+student.getAge()+"   性别:"+student.getSex()+"   mother:"+student.getMother().toString());    }}姓名:小晴   年龄:15   性别:男   mother:andy姓名:小晴   年龄:100   性别:男   mother:alice姓名:小晴   年龄:15   性别:男   mother:alice

可见浅拷贝只会复制值变量,对于引用类型还是只想同一个对象。

3.深拷贝
顾名思义,深拷贝就是要拷贝一个完全独立的对象。在浅拷贝的基础上,我只需要把引用类型变量指向不同的对象即可。只需修改:

//浅拷贝 public void setMother(String name){mother.setName(name);} //深拷贝 public void setMother(String name) {        mother=new Mother();//重新创建一个对象,即可指向不同的对象空间了。        mother.setName(name);    }姓名:小晴   年龄:15   性别:男   mother:andy姓名:小晴   年龄:100   性别:男   mother:alice姓名:小晴   年龄:15   性别:男   mother:andy

另一种方式,对Mother对象也进行clone方法覆盖:

package com.example.demo.common;public class Student implements Cloneable {    private String name;    private int age;    private String sex;    private Mother mother;    public Student(String name, int age, String sex) {        this.name = name;        this.age = age;        this.sex = sex;        this.mother = new Mother();    }    public Mother getMother() {        return mother;    }    public void setMother(String name) {//        mother=new Mother();        mother.setName(name);    }    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 int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public Object clone() {        Student student=null;        try {            student=(Student) super.clone();            student.mother=(Mother)mother.clone();            return student;        } catch (CloneNotSupportedException e) {            e.printStackTrace();            return null;        }    }}class MainTest {    public static void main(String[] args) {        Student student = new Student("小晴 ", 15, "男");        student.setMother("andy");        System.out.println("姓名:" + student.getName() + "  年龄:" + student.getAge() + "   性别:" + student.getSex() + "   mother:" + student.getMother().toString());        Student student1 = (Student) student.clone();        student1.setAge(100);        student1.setMother("alice");        System.out.println("姓名:" + student1.getName() + "  年龄:" + student1.getAge() + "   性别:" + student1.getSex() + "   mother:" + student1.getMother().toString());        System.out.println("姓名:" + student.getName() + "  年龄:" + student.getAge() + "   性别:" + student.getSex() + "   mother:" + student.getMother().toString());    }}class Mother implements Cloneable {    private String name;    public void setName(String name) {        this.name = name;    }    public String toString() {        return name;    }    public Object clone(){        try {            Mother mother=(Mother)super.clone();            return mother;        } catch (CloneNotSupportedException e) {            e.printStackTrace();            return null;        }    }}
原创粉丝点击