在Java中除了new关键字可以创建对象(实例化对象)以外,使用Cloneable接口也可以实现对象的创建,具体用法如下:

Cloneable接口比较特殊,虽然他是一个口接口,但是我们也必须重写clone方法才能使用,这是语法规定,需要特殊记忆;

class Money implements Cloneable{
    public double m = 12.5;

    @Override //重写clone方法
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Person implements Cloneable{
    public int age;
    public Money money = new Money();

    public void eat() {
        System.out.println("吃!");
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                '}';
    }

    @Override //重写clone方法
    protected Object clone() throws CloneNotSupportedException {
        Person tmp = (Person)super.clone(); //为了实现对象的深拷贝,这里需要特殊处理
        tmp.money = (Money) this.money.clone(); //再次进行money对象的clone,实现深拷贝
        return tmp;
        //return super.clone();
    }
}
public class TestDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        Person person2 = (Person)person.clone();
        System.out.println(person.money.m);
        System.out.println(person2.money.m);
        System.out.println("=====================");
        person2.money.m = 99.99;
        System.out.println(person.money.m);
        System.out.println(person2.money.m);
    }


    public static void main1(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        person.age = 99;

        Person person2 = (Person)person.clone();
        System.out.println(person2);

        System.out.println("==================");
        person2.age = 199;

        System.out.println(person);
        System.out.println(person2);

    }
}

lua tab深拷贝 深拷贝需要实现cloneable接口_System


如果对person类进行clone,则会在堆上clone出一个一模一样的对象,对象的地址不用,在栈上的引用也就是不同的;

lua tab深拷贝 深拷贝需要实现cloneable接口_java_02


因为这里进行的就是深拷贝,所以更改person2中的age为199,不影响person中的age,为99;他们是两块独立存在的空间

lua tab深拷贝 深拷贝需要实现cloneable接口_原型模式_03


然而另一种情况:

lua tab深拷贝 深拷贝需要实现cloneable接口_System_04


lua tab深拷贝 深拷贝需要实现cloneable接口_System_05


lua tab深拷贝 深拷贝需要实现cloneable接口_原型模式_06

如果进行clone的对象中引用了另一个对象,则clone的情况如图所示,此时person进行了clone,创建了另一快空间,有自己的地址,然而此时这个新的person2类中的money对象还是在引用之前的那个money对象,所以此时就行修改,修改了money类中M的值为99.99,此时两个person类都同时引用了这个对象,值同时被修改了

lua tab深拷贝 深拷贝需要实现cloneable接口_开发语言_07


这就是浅拷贝;

要想进行深拷贝,则需要修改一下重写的clone方法(注意处理异常):

lua tab深拷贝 深拷贝需要实现cloneable接口_lua tab深拷贝_08


让money对象单独就行clone一份,这样就是两个不一样的person对象引用两个不一样的money对象,修改其一就不会影响另一个了,也就是两块不一样的空间;

lua tab深拷贝 深拷贝需要实现cloneable接口_System_09


lua tab深拷贝 深拷贝需要实现cloneable接口_开发语言_10

lua tab深拷贝 深拷贝需要实现cloneable接口_开发语言_11

这就是实现了深拷贝!