cloneable

一个类实现Cloneable接口来指示Object.clone()方法,该方法对于该类的实例进行字段的复制是合法的。在不是先Cloneable接口的实力上调用对象的克隆方法会导致异常java.lang.CloneNotSupportedException(不支持克隆异常,该类直接继承了Exception

protected native Object clone() throws CloneNotSupportedException;

克隆的前提条件

被克隆对象所在的类必须实现Cloneable接口

必须重写clone方法在其中

因为在Object中定义的对象修饰符是protected所以子类需要覆盖该方法才能使用

浅拷贝

class User implements Cloneable{
    public String name;
    public int age;
    Dog dog;

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", dog=" + dog +
                '}';
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Dog{
    public String name;

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                '}';
    }


}

public class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        User user = new User();
        Dog dog = new Dog();
        dog.name="旺财";
        user.name="用户1";
        user.age=19;
        user.dog=dog;
        User user2=(User)user.clone();
        //User{name='我改名了', age=19, dog=Dog{name='我狗也改名了'}}
        user.name="我改名了";
        //User{name='用户1', age=19, dog=Dog{name='我狗也改名了'}}
        user.dog.name="我狗也改名了";
        System.out.println(user);
        System.out.println(user2);
    }
}

从上面代码不难看出一个对象中的内部对象还是拷贝的是地址

要解决这个问题可以用深拷贝来进行解决

深拷贝

class User implements Cloneable{
    public String name;
    public int age;
    Dog dog;

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", dog=" + dog +
                '}';
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        //先克隆出来一个用户对象
        User user=(User)super.clone();
        //再克隆出来一个dog对象
        Dog dog=(Dog)this.dog.clone();
        //把克隆之后的dog赋值给用户
        user.dog=dog;
        return user;
    }
}
//dog类也需要继承这个接口
class Dog implements Cloneable{
    public String name;

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                '}';
    }

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

public class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        User user = new User();
        Dog dog = new Dog();
        dog.name="旺财";
        user.name="用户1";
        user.age=19;
        user.dog=dog;
        User user2=(User)user.clone();
        //User{name='我改名了', age=19, dog=Dog{name='我狗也改名了'}}
        user.name="我改名了";
        //User{name='用户1', age=19, dog=Dog{name='旺财'}}
        user.dog.name="我狗也改名了";
        System.out.println(user);
        System.out.println(user2);
    }
}
Last modification:April 21, 2022
如果觉得我的文章对你有用,请随意赞赏