深拷贝、浅拷贝

把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;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值