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);
}
}