代码说明java中的赋值、浅拷贝、深拷贝

Student类:

    public class Student implements Cloneable,Serializable{
        private static final long serialVersionUID = 4736229991747913221L;
        private int age;
        private Car car;
     
        //篇幅原因省略构造/get/set方法
     
        @Override
        protected Student clone() throws CloneNotSupportedException {
            // TODO Auto-generated method stub
            return (Student) super.clone();
        }
    }

Car类:

    public class Car implements Cloneable,Serializable{
        private static final long serialVersionUID = 1705363073258599641L;
        private int price;
        
        //篇幅原因省略构造/get/set方法
    }

 

一、赋值

     
    public void test1() {
        Student zhang=new Student();
        zhang.setAge(5);
        Student wang=new Student();
        System.out.println(zhang+" "+wang);
        wang=zhang;
        System.out.println(zhang+" "+wang);
        System.out.println(wang.getAge());
        wang.setAge(6);
        System.out.println(zhang.getAge());
    }

运行结果:

    clone.Student@4459eb14 clone.Student@5a2e4553
    clone.Student@4459eb14 clone.Student@4459eb14
    5
    6

引用类型进行赋值时,赋的值是引用的值,wang=zhang;即将zhang的地址赋值给wang,此时两者指向同一块内存。

二、浅克隆

    public void test2() throws CloneNotSupportedException{
        Student zhang=new Student(5, new Car(10000));
        Student wang=zhang.clone();
        System.out.println(zhang+" "+wang);
        System.out.println(wang.getAge()+"  "+wang.getCar().getPrice());
        //改变wang中的普通类型
        wang.setAge(6);
        //改变wang中的引用类型
        wang.getCar().setPrice(200000);
        //zhang中的普通类型不变,引用类型被改变
        System.out.println(zhang.getAge()+"  "+zhang.getCar().getPrice());
    }

运行结果:

    clone.Student@4459eb14 clone.Student@5a2e4553
    5  10000
    5  200000

实现Cloneable接口并重写clone方法(见Student类)进行浅拷贝,该方法使wang拥有与zhang不同的引用,但其中的引用类型Car依旧指向同一地址。

三、深克隆

实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆

    public void test3() throws Exception{
        Student zhang=new Student(5, new Car(10000));
        Student wang=MyUtil.clone(zhang);
        System.out.println(zhang+" "+wang);
        System.out.println(wang.getAge()+"  "+wang.getCar().getPrice());
        //改变wang中的普通类型
        wang.setAge(6);
        //改变wang中的引用类型
        wang.getCar().setPrice(200000);
        //zhang中的普通类型不变,引用类型被改变
        System.out.println(zhang.getAge()+"  "+zhang.getCar().getPrice());
    }

MyUtil类:

    public class MyUtil {
        private MyUtil() {
            throw new AssertionError();
        }
        @SuppressWarnings("unchecked")
        public static <T extends Serializable> T clone(T obj) throws Exception {
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bout);
            oos.writeObject(obj);
     
            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bin);
            return (T) ois.readObject();
        }
    }

运行结果:

    clone.Student@6d5380c2 clone.Student@3d012ddd
    5  10000
    5  10000

 该方法使wang拥有与zhang不同的引用,其中的引用类型Car也指向不同地址。


---------------------
作者:Aooper
来源:CSDN
原文:https://blog.csdn.net/Aooper/article/details/82262071
版权声明:本文为博主原创文章,转载请附上博文链接!

posted @ 2019-07-22 11:17  天涯海角路  阅读(194)  评论(0)    收藏  举报