Java 中 引用拷贝、浅拷贝、深拷贝

1、前言基础知识

1、Java得数据类型:基本类型,引用类型
2、基本类型:保存得值本身
3、引用数据类型:保存的指向堆内存中数据地址

2、定义

对象拷贝指的就是将一个对象的所有属性(成员属性)拷贝到一个有着相同类型的对象中去

分类:引用拷贝、浅拷贝、深拷贝(深拷贝 浅拷贝都是对象拷贝)

3、引用拷贝
引用拷贝只是把引用地址进行拷贝,都指向同一个对象

/**
 * @Author charles.yao
 * @Description 用户信息
 * @Date 2023/2/13 14:30
 */
@NoArgsConstructor
@AllArgsConstructor
@Data
public class UserInfo {
    private String userName;
    private String userAge;
}

/**
 * @Author charles.yao
 * @Description 引用拷贝测试
 * @Date 2023/2/13 14:31
 */
public class QuoteCopyTest {
    public static void main(String[] args) {
        UserInfo userInfo = new UserInfo("张三", "18");
        UserInfo userCopy = userInfo;
        System.out.println("原用户"+userInfo.toString());
        System.out.println("引用拷贝"+userCopy.toString());
        System.out.println("原用户与引用拷贝比较"+userCopy.equals(userInfo));
    }
}

运行结果:

原用户UserInfo(userName=张三, userAge=18)
引用拷贝UserInfo(userName=张三, userAge=18)
原用户与引用拷贝比较true

image-20230213153111158

4、浅拷贝

被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。即对象的浅拷贝会对“主”对象进行拷贝,但不会复制主对象里面的对象。"里面的对象“会在原来的对象和它的副本之间共享。

代码示例


/**
 * @Author charles.yao
 * @Description 浅拷贝类
 * @Date 2023/2/13 14:53
 */
@NoArgsConstructor
@AllArgsConstructor
@Data
public class UserInfo implements Cloneable{
    private String userName;
    private String userAge;
    private Animal animal;
    @Override
    protected UserInfo clone() throws CloneNotSupportedException {
        return (UserInfo) super.clone();
    }
}



/**
 * @Author charles.yao
 * @Description
 * @Date 2023/2/13 14:54
 */
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Animal implements Cloneable {
    private String userName;
    private String userAge;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}


/**
 * @Author charles.yao
 * @Description 浅拷贝测试
 * @Date 2023/2/13 14:57
 */
public class ShallowCopyTest {
    public static void main(String[] args) {
        try {
            UserInfo userInfo = new UserInfo();
            userInfo.setUserName("张三");
            userInfo.setUserAge("1223");
            userInfo.setAnimal(new Animal("111", "2122"));
            UserInfo clone = userInfo.clone();
            System.out.println("原数据" + userInfo.toString());
            System.out.println("拷贝之后" + clone.toString());
            userInfo.setUserName("二狗");
            System.out.println("修改后原数据" + userInfo.toString());
            System.out.println("修改后拷贝之后" + clone.toString());
            System.out.println(userInfo == clone);
            System.out.println(userInfo.getAnimal() == clone.getAnimal());
            userInfo.getAnimal().setUserName("二狗");

            System.out.println("原数据动物" + userInfo.getAnimal().toString());
            System.out.println("拷贝之后动物" + clone.getAnimal().toString());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

运行结果

原数据UserInfo(userName=张三, userAge=1223, animal=Animal(userName=111, userAge=2122))
拷贝之后UserInfo(userName=张三, userAge=1223, animal=Animal(userName=111, userAge=2122))
修改后原数据UserInfo(userName=二狗, userAge=1223, animal=Animal(userName=111, userAge=2122))
修改后拷贝之后UserInfo(userName=张三, userAge=1223, animal=Animal(userName=111, userAge=2122))
false
true
原数据动物Animal(userName=二狗, userAge=2122)
拷贝之后动物Animal(userName=二狗, userAge=2122)

image-20230213160247424

6、深拷贝

深拷贝是一个整个独立的对象拷贝,深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。

代码示例


/**
 * @Author charles.yao
 * @Description 浅拷贝类
 * @Date 2023/2/13 14:53
 */
@NoArgsConstructor
@AllArgsConstructor
@Data
public class UserInfo implements Cloneable {
    private String userName;
    private String userAge;
    private Animal animal;

    @Override
    protected UserInfo clone() throws CloneNotSupportedException {

        UserInfo userInfo = (UserInfo) super.clone();
        userInfo.setAnimal((Animal) animal.clone());
        return userInfo;
    }
}


/**
 * @Author charles.yao
 * @Description
 * @Date 2023/2/13 14:54
 */
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Animal implements Cloneable {
    private String userName;
    private String userAge;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}


/**
 * @Author charles.yao
 * @Description 浅拷贝测试
 * @Date 2023/2/13 14:57
 */
public class DeepCopyTest {
    public static void main(String[] args) {
        try {
            UserInfo userInfo = new UserInfo();
            userInfo.setUserName("张三");
            userInfo.setUserAge("1223");
            userInfo.setAnimal(new Animal("111", "2122"));
            UserInfo clone = userInfo.clone();
            System.out.println("原数据" + userInfo.toString());
            System.out.println("拷贝之后" + clone.toString());
            System.out.println(userInfo == clone);
            System.out.println(userInfo.getAnimal() == clone.getAnimal());
            userInfo.getAnimal().setUserName("二狗");

            System.out.println("原数据动物" + userInfo.getAnimal().toString());
            System.out.println("拷贝之后动物" + clone.getAnimal().toString());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

测试结果

原数据UserInfo(userName=张三, userAge=1223, animal=Animal(userName=111, userAge=2122))
拷贝之后UserInfo(userName=张三, userAge=1223, animal=Animal(userName=111, userAge=2122))
false
false
原数据动物Animal(userName=二狗, userAge=2122)
拷贝之后动物Animal(userName=111, userAge=2122)

image-20230213161224941

猜你喜欢

转载自blog.csdn.net/CharlesYooSky/article/details/129011195