Java基础笔记之深拷贝与浅拷贝(protected && Cloneable)

关于Java深拷贝浅拷贝问题


前言

在详细说明深拷贝浅拷贝之前,我先给出一些相关代码,如下:

*********Person***********
class Person implements Cloneable{
	private String name;        //姓名
    private Integer age;        //年龄
    private Address address;    //住址
	
	//注意!!!setter/getter方法和无参、有参构造方法省略...
	
    @Override
    public Person clone() {
        try {
            return (Person) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }
}
*********Address***********
class Address {
    private String location;    //位置

	//注意!!!setter/getter方法和无参、有参构造方法省略...
}

一、浅拷贝

浅拷贝会在堆上创建一个新的对象,不过,如果原对象内部的属性是引用类型的话,浅拷贝会直接复制内部对象的引用地址,也就是说拷贝对象和原对象共用同一个内部对象。
代码:

public class ShallowAndDeepCopy {
    public static void main(String[] args) {
        Person person = new Person("yy", Integer.valueOf(20), new Address("某地"));
        Person shallowCopy = person.clone();
        System.out.println(person == shallowCopy);  //false
        System.out.println(person.getAddress() == shallowCopy.getAddress());    //ture
    }
}

运行结果:
运行结果1


二、深拷贝

深拷贝会完全复制整个对象,包括这个对象所包含的内部对象。
代码修改如下:

*********Personclone()***********
 @Override
    public Person clone() {
        try {
            Person person = (Person) super.clone();
            person.setAddress(person.getAddress().clone());
            return person;
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }
*********Addressclone()***********
// class Address implements Cloneable
@Override
    public Address clone() {
        try {
            return (Address) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }

运行结果:
运行结果2


总结

在这里插入图片描述


扩展问题?

1. 为什么在类ShallowAndDeepCopy的main方法中创建Person类的实例person并调用clone() 的时候,Person类一定要实现Cloneable接口?

如果 Person 类不实现 Cloneable 接口,调用 clone 方法时会导致编译错误。因为如果不对重写的clone() 进行逻辑修改的话,本质上调用的时Object类中的clone(),而该方法是protected修饰的。

protected修饰符修饰的方法只能在本类、本包以及子类中使用,而在类ShallowAndDeepCopy中使用会报编译错误。也即是说,protected修饰的成员可以被子类(不同包的子类或同包的子类)访问是指父类的protected成员被子类继承,子类可以直接使用;不是在子类方法中创建父类对象,然后通过父类对象调用protected权限的方法。

2. Cloneable 接口

Cloneable 接口是 Java 中的一个标记接口(marker interface),它在设计上并没有包含任何方法。其主要作用是向类的使用者表示该类是可克隆的,即可以使用 Object 类的 clone 方法创建该类对象的副本。

Object 类中的 clone 方法声明了抛出 CloneNotSupportedException 异常。如果一个类希望使用 Object 类的 clone 方法而不抛出异常,那么该类必须实现 Cloneable 接口。否则,Object 类的 clone 方法在调用时可能会抛出异常。

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值