美文网首页
2020-07-26Java 中深拷贝与浅拷贝的区别?

2020-07-26Java 中深拷贝与浅拷贝的区别?

作者: fjasmin | 来源:发表于2020-07-26 23:34 被阅读0次

    在Java中浅拷贝和深拷贝就是在这个基础之上做的区分,如果在拷贝这个对象的时候,只对基本数据类型进行了拷贝,而对引用数据类型只是进行了引用的传递,而没有真实的创建一个新的对象,则认为是浅拷贝。反之,在对引用数据类型进行拷贝的时候,创建了一个新的对象,并且复制其内的成员变量,则认为是深拷贝。
    所以到现在,就应该了解了,所谓的浅拷贝和深拷贝,只是在拷贝对象的时候,对 类的实例对象 这种引用数据类型的不同操作而已。
    总结来说:

    1. 浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。并且它们之间的hashcode不一样,只是其数据类型字段相同。
    2. 深拷贝:是对对象,数据类型值and 它们之间的hashcode拷贝;进行对象完完全全的clone();原对象与新对象对比完全相同。

    浅拷贝:

    1.实现Cloneable

    2.成员变量是基本数据类型,也包括String类型

    public class ShallowCopy implements Cloneable {
    private int age;
    private String name;
    
    public ShallowCopy(int age, String name) {
        this.age = age;
        this.name = name;
    }
    
    @Override
    public Object clone() {
        ShallowCopy s = null;
        try {
            s = (ShallowCopy) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return s;
    }
    
    @Override
    public String toString() {
        return "{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
    
    public static void main(String[] args) {
    
        ShallowCopy sample = new ShallowCopy(1, "wislie");
    
        ShallowCopy cloneObj = (ShallowCopy) sample.clone();
    
        System.out.println("浅度拷贝 (cloneObj == sample):" + (cloneObj == sample)); //false
        System.out.println("sample:" + sample); //sample:{age=1, name='wislie'}
        System.out.println("cloneObj:" + cloneObj); //cloneObj:{age=1, name='wislie'}
    }
    }
    

    深拷贝:

    有两种实现方式,一种是实现Cloneable,成员变量需要有引用类型的对象;另一种实现了Serializable,对成员变量没有限制.

    实现Cloneable的方式:

    public class DeepCopy implements Cloneable {
    
    private String value;
    private ShallowCopy shaderCopy;
    
    public DeepCopy(String value, ShallowCopy shaderCopy) {
        this.value = value;
        this.shaderCopy = shaderCopy;
    }
    
    public String getValue() {
        return value;
    }
    
    public void setValue(String value) {
        this.value = value;
    }
    
    public ShallowCopy getShaderCopy() {
        return shaderCopy;
    }
    
    public void setShaderCopy(ShallowCopy shaderCopy) {
        this.shaderCopy = shaderCopy;
    }
    
    @Override
    protected Object clone() {
        DeepCopy d = null;
        try {
            d = (DeepCopy) super.clone();
            if(shaderCopy != null){
                d.setShaderCopy((ShallowCopy) shaderCopy.clone());
            }
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return d;
    }
    
    @Override
    public String toString() {
        return "{" +
                "value='" + value + '\'' +
                ", shaderCopy=" + shaderCopy +
                '}';
    }
    
    public static void main(String[] args) {
        DeepCopy sample = new DeepCopy("high", new ShallowCopy(12, "wislie"));
        DeepCopy cloneObj = (DeepCopy) sample.clone();
        System.out.println("深度拷贝 (cloneObj == sample):" + (cloneObj == sample)); //false
        System.out.println("sample:" + sample); //{value='high', shaderCopy={age=12, name='wislie'}}
        System.out.println("cloneObj:" + cloneObj);//{value='high', shaderCopy={age=12, name='wislie'}}
    }
    }
    

    实现Serializable的方式

    public class DeepCopy2 implements Serializable {
    
    private static final long serialVersionUID = 369285298572961L;  //最好是显式声明ID
    private int len;
    private Inner inner;
    
    public DeepCopy2(int len, Inner inner) {
        this.len = len;
        this.inner = inner;
    }
    
    static class Inner implements Serializable {
        private static final long serialVersionUID = 369285298572941L;  //最好是显式声明ID
    
        private String color;
        private int alpha;
    
        public Inner(String color, int alpha) {
            this.color = color;
            this.alpha = alpha;
        }
    
        @Override
        public String toString() {
            return "Inner{" +
                    "color='" + color + '\'' +
                    ", alpha=" + alpha +
                    '}';
        }
    }
    
    @Override
    public String toString() {
        return "DeepCopy2{" +
                "len=" + len +
                ", inner=" + inner +
                '}';
    }
    
    private DeepCopy2 deepClone() {
        DeepCopy2 data = null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(this);
            //将流序列化成对象
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            data = (DeepCopy2) ois.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return data;
    }
    
    public static void main(String[] args) {
        DeepCopy2 sample = new DeepCopy2(10, new Inner("blue", 255));
        DeepCopy2 copySample = sample.deepClone();
    
        System.out.println("sample==copySample:" + (sample == copySample)); //false
        System.out.println("sample:" + sample); //DeepCopy2{len=10, inner=Inner{color='blue', alpha=255}}
        System.out.println("copySample:" + copySample); //DeepCopy2{len=10, inner=Inner{color='blue', alpha=255}}
    }
    }
    

    不管是浅拷贝还是深拷贝,对象的地址都变了;

    相关文章

      网友评论

          本文标题:2020-07-26Java 中深拷贝与浅拷贝的区别?

          本文链接:https://www.haomeiwen.com/subject/ejvnlktx.html