• Java-Object.clone()-浅复制与深复制


    引言

    在某些场景中,我们需要获取到一个对象的拷贝用于某些处理。这时候就可以用到Java中的Object.clone方法进行对象复制,得到一个一模一样的新对象。但是在实际使用过程中会发现:当对象中含有可变的引用类型属性时,在复制得到的新对象对该引用类型属性内容进行修改,原始对象响应的属性内容也会发生变化,这就是"浅拷贝"的现象。

    浅拷贝的例子

    Address类:clone/Address.java

    package clone;
    
    public class Address implements Cloneable{//实现cloneable接口
        private String province;
        private String city;
        public Address() {
            
        }
        public Address(String province, String city) {
            this.province = province;
            this.city = city;
        }
        public Address clone() throws CloneNotSupportedException {
            Address newAdd = (Address)super.clone();
            return newAdd;
        }
        
        public String getProvince() {
            return province;
        }
        public void setProvince(String province) {
            this.province = province;
        }
        public String getCity() {
            return city;
        }
        public void setCity(String city) {
            this.city = city;
        }
        public String toString() {
            return "Province:"+province+"   city:"+city;
        }
    }

    student类:clone/student.java

    package clone;
    
    public class student implements Cloneable{
        private String name;//String被声明为final,是不可变类型,无法修改,所以就算是浅复制也不影响。
        private int age;//基本类型,clone的时候直接copy
        private Address address;//Address不是基本类型,并且可变,默认的clone的时候只会复制一个引用,这样clone前后的两个对象都引用同一个Address实例对象。
        public student() {
            
        }
        public student(String name,int age, Address address) {
            this.name = name;
            this.age = age;
            this.address = address;
        }
        public student clone() throws CloneNotSupportedException {
            student newStu = (student) super.clone();
            newStu.address = (Address) address.clone();//不加这一句,对于Address来说就是一个浅复制。
            return newStu;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Address getAddress() {
            return address;
        }
        public void setAddress(Address address) {
            this.address = address;
        }
        public String toString() {
            return "name:"+name+"   age:"+age+"Address Info:"+address.toString();
        }
    }

    test类: clone/test.java

    package clone;
    
    public class test {
        public static void main(String[] args) throws CloneNotSupportedException {
            Address add = new Address("四川","成都");
            student a = new student("小明",18,add);
            
            student b = a.clone();//克隆a,赋值给b
            add.setCity("广安");//浅复制的话,a和b都引用add这个实例对象,则此次修改值势必会影响a和b。深复制则不影响。
            System.out.println(a.toString());
            System.out.println(b.toString());
        }
    }

    输出

    name:小明   age:18Address Info:Province:四川   city:广安
    name:小明   age:18Address Info:Province:四川   city:成都

    从输出结果来看,对add实例对象的修改并没有影响到b这个引用变量,所以本次clone不是浅复制。

  • 相关阅读:
    使用强名称为程序集签名
    使用SN.exe对.Net生成的程序集进行签名
    .Net 程序集 签名工具sn.exe 密钥对SNK文件 最基本的用法
    MongoDB查询
    mongo批量写入es
    用 Spark 处理复杂数据类型(Array、Map、JSON字符串等)
    kafka消费者
    kafka生产者
    Pyspark常用API总结
    selenium+chromedriver+python3 不加载图片
  • 原文地址:https://www.cnblogs.com/xxxxxiaochuan/p/13715104.html
Copyright © 2020-2023  润新知