java 浅拷贝和深拷贝

java 浅拷贝和深拷贝

简单理解:

浅拷贝:拷贝地址。原变量改变,新变量也会受到影响

深拷贝:拷贝值,开辟一块新的内存返回。原变量改变,新变量不会受到影响

拷贝基本数据类型

拷贝基本数据类型字面量,都是拷贝值

拷贝引用类型

浅拷贝:

  1. 直接赋值,直接返回的是克隆对象的引用地址

    测试代码:

    public class User {
        public User(Integer age) {
            this.age = age;
        }
        public Integer getAge() {
            return age;
        }
        public void setAge(Integer age) {
            this.age = age;
        }
        private Integer age;
        public static void main(String[] args) {
            User user = new User(10);
            User user2 = user;
            user2.setAge(100);
            System.out.println(user == user2); // true
            System.out.println(user.getAge()); // 100
        }
    }
    
    
  2. Cloneable接口
    测试代码:

    public class User implements Cloneable {
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    
        private Integer age;
        private String name;
        private int height;
        private Son son;
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getHeight() {
            return height;
        }
    
        public void setHeight(int height) {
            this.height = height;
        }
    
        public Son getSon() {
            return son;
        }
    
        public void setSon(Son son) {
            this.son = son;
        }
    
        public User(Integer age, String name, int height, Son son) {
            this.age = age;
            this.name = name;
            this.height = height;
            this.son = son;
        }
    
        public static void main(String[] args) throws CloneNotSupportedException {
            User user = new User(10, "name", 180, new Son("xxx"));
            User user2 = (User) user.clone();
            user2.getSon().setName("yyy");
            System.out.println(user.getSon() == user2.getSon()); // true
            System.out.println(user.getSon().getName()); // yyy
        }
    }
    

深拷贝:

  1. Cloneable的clone其实只能拷贝一层(就是和直接赋值不相同的是,user = user2,user和user2地址一样,clone是user和user2的地址不一样,user和user2里面的第一层也不一样,再深入就全是一样的),如果我们重写clone,遍历层级进行clone就可达到深拷贝
  2. 各种序列化拷贝,例如:JSON序列化,Object序列化流,需要实现Serializable接口,速度相对慢
    注意点:被transient修饰不参与序列化

不可变类的特殊性:

例如像这种String、包装类,这种都是不可变类,它们不能改变内容,如果要改变,是开辟新的内存,返回地址,而不是改变内存里的数据,所以不可变类的拷贝都是引用的地址

posted @ 2022-05-10 21:01  isyues  阅读(198)  评论(0编辑  收藏  举报