java拷贝基础

###浅拷贝

创建一个新对象,然后将当前对象的非静态字段复制到该新对象,如果字段是值类型的, 那么对该字段执行复制;如果该字段是引用类型的话,则复制引用但不复制引用的对象。即如果复制的对象里面的属性为值类型则直接复制值类型过去,如果是引用类型则直接复制地址(不复制对象),所以原对象里面的引用属性如果指向地址改变的话拷贝的对象里面的将不会改变,具体如下面代码所示。(值类型拷贝值,引用类型拷贝地址)

public class MyTest {
    public static void main(String[] args) throws InterruptedException, CloneNotSupportedException {
         A a = new A();
         a.setName("张三");
         People p1 = new People();
         p1.setA(a);
         p1.setB(5);
         People p2 = (People) p1.clone();
         //因为创建的新对象所以地址不一样,返回false
         System.out.println(p1 == p2);
         //因为拷贝对象地址,所以返回true
         System.out.println(p1.getA() == p2.getA());
         System.out.println(p1.getA().getName() + ": " + p1.getB());
         System.out.println(p2.getA().getName() + ": " + p2.getB());
         a.setName("李四");
         p1.setB(10);
         //因为此时地址相同,所以p1中的a改变p2中的a也会改变
         System.out.println(p1.getA().getName() + ": " + p1.getB());
         System.out.println(p2.getA().getName() + ": " + p2.getB());
         A a2 = new A();
         a2.setName("王五");
         p1.setA(a2);
         //此时p1中的a变成了新对象,和p2中的a指向的不同的地址
         System.out.println(p1.getA().getName() + ": " + p1.getB());
         System.out.println(p2.getA().getName() + ": " + p2.getB());
    }
}
class A{
    private String name;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
class People  implements Cloneable {
    private A a;
    private int b;

    public int getB() {
        return b;
    }

    public void setB(int b) {
        this.b = b;
    }

    public A getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a;
    }
/**
浅拷贝
*/
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

}

false
true
张三: 5
张三: 5
李四: 10
李四: 5
false
王五: 10
李四: 5

###深拷贝

public class MyTest {
    public static void main(String[] args) throws InterruptedException, CloneNotSupportedException {
         A a = new A();
         a.setName("张三");
         People p1 = new People();
         p1.setA(a);
         p1.setB(5);
         People p2 = (People) p1.clone();
         System.out.println(p1 == p2);
         System.out.println(p1.getA() == p2.getA());
         System.out.println(p1.getA().getName() + ": " + p1.getB());
         System.out.println(p2.getA().getName() + ": " + p2.getB());
         a.setName("李四");
         p1.setB(10);
         System.out.println(p1.getA().getName() + ": " + p1.getB());
         System.out.println(p2.getA().getName() + ": " + p2.getB());
         A a2 = new A();
         a2.setName("王五");
         p1.setA(a2);
         System.out.println(p1.getA().getName() + ": " + p1.getB());
         System.out.println(p2.getA().getName() + ": " + p2.getB());
    }
}
class A implements Cloneable{
    private String name;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class People  implements Cloneable {
    private A a;
    private int b;

    public int getB() {
        return b;
    }

    public void setB(int b) {
        this.b = b;
    }

    public A getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a;
    }

    @Override
    //深拷贝
    public Object clone() throws CloneNotSupportedException {
        People p = null;
        try {
            p = (People) super.clone();
        } catch (CloneNotSupportedException e) {
            System.out.println(e.toString());
        }
        p.a= (A) a.clone();
        return p;
    }
}

false
false
张三: 5
张三: 5
李四: 10
张三: 5
王五: 10
张三: 5
可以看出深拷贝拷贝过后的所有对象都和原本的无关,直接为为拷贝的开辟了一片空间。
###直接赋值
我们平常最常用的,即直接p2=p1;这样p1和p2都是同一个对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值