Object类clone方法
Java要想自定义的类的对象能被复制,自定义类要实现Cloneable接口的clone方法:
浅拷贝
按位拷贝对象,会创建一个新对象,如果属性是基本类型,拷贝的的是基本类型的值;如果属性是引用类型,拷贝的是内存地址。
package TestObject;
public class TestClone {
public static void main(String[] args) {
Person ming = new Person("小明");
Animal cat = new Animal("喵");
ming.setPet(cat);
System.out.println(ming.toString());
try {
Person hong = (Person) ming.clone();//赋值对象
hong.setName("小红");
hong.getPet().setName("汪");
System.out.println(hong.toString());
System.out.println(ming.toString());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
class Person implements Cloneable{
private String name;
private Animal pet;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Animal getPet() {
return pet;
}
public void setPet(Animal pet) {
this.pet = pet;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", pet=" + pet +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Animal{
private String name;
public Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
'}';
}
}
结果:
ming和hong指向同一个Animal对象,所以hong对Animal的更改使得ming
的Animal值变化。
注:String类型通过常量赋值相当于基本数据类型,通过new关键字创建对象属于引用数据类型。
深拷贝
深拷贝会拷贝所有属性,同时拷贝属性指向动态分配的内存。深拷贝速度较慢同时花销大。
//PerSon类重写clone方法
@Override
protected Object clone() throws CloneNotSupportedException {
Person clonePerSon =(Person) super.clone();//克隆一个人
clonePerSon.pet = (Animal)pet.clone();//还要克隆一个动物
return clonePerSon;//返回真正的克隆人
}
//也要实现Cloneable接口
class Animal implements Cloneable{
private String name;
public Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
'}';
}
}
结果:
总结:深拷贝,其中一份的任何属性值的改变不会给另一份属性值造成影响,浅拷贝改变其中一份引用类型的属性值会对引起另一份属性值改变。