Java对象的clone
Java对象的clone
在程序开发中,有时可能好会遇到下列情况:已经存在一个对象A,现在需要一个与对象A完全相同的B对象,并对B对象的值进行修改,但是A对象的原有的属性值不能改变。这时,如果使用Java提供的对象赋值语句B=A,当修改B对象值后,A对象的值也会被修改,实际上是引用传递。那么应该如何实现创建一个和对象A完全相同的对象B,而且修改对象B时,对象A的属性值不被改变呢?
浅clone
所谓浅克隆就是说被克隆的对象的各个属性都是基本类型,而不是引用类型(接口、类、数组),若基本类型和引用类型都含有,且未重写clone方法,则只能克隆基本类型。如果存在引用类型的属性也需要clone,则需要进行深克隆。下面分别演示。
先创建一个Address,表示人员地址,并且作为人员类的成员变量
public class Address {
public String province;
public Address(String province) {
this.province = province;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Address{" +
"province='" + province + '\'' +
'}';
}
}
再创建people,且可以clone
public class People implements Cloneable{ //需要实现Cloneable接口
public String name;
public int age;
public Address address;
@Override
protected Object clone() throws CloneNotSupportedException { //重写clone方法
return super.clone();
}
public People(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", age=" + age +
", address=" + address +
'}';
}
}
最后创建一个测试类
public class cloneTest {
public static void main(String[] args) throws CloneNotSupportedException {
People c1 = new People("Tom",22,new Address("山东"));
Object c2 = c1.clone();
System.out.println(c2.toString());
c1.setAge(33);//尝试改变c1基本数据类型变量
c1.getAddress().setProvince("北京");//尝试改变c1引用类型的成员变量
System.out.println(c2.toString());
}
}
结果
People{name='Tom', age=22, address=Address{province='山东'}}
People{name='Tom', age=22, address=Address{province='北京'}}
QA
通过运行结果我们发现,虽然c2是被c1 clone来的,但是改变c1的引用类型的成员变量的时候,clone而来的c2对应的变量也被改变了。同时,c1基本数据类型的改变,没有影响到c2,说明c1的基本数据类型变量被成功clone到c2,但引用类型变量未成功clone。则需要深clone。
深clone
public class Address implements Cloneable{
public String province;
public Address(String province) {
this.province = province;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
/*@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}*/
@Override
protected Address clone() throws CloneNotSupportedException {
return (Address) super.clone();
}
@Override
public String toString() {
return "Address{" +
"province='" + province + '\'' +
'}';
}
}
public class People implements Cloneable{
public String name;
public int age;
public Address address;
/*@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}*/
@Override
protected People clone() throws CloneNotSupportedException {
People people;
people= (People) super.clone();
people.address=address.clone();
return people;
}
public People(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", age=" + age +
", address=" + address +
'}';
}
}
public class cloneTest {
public static void main(String[] args) throws CloneNotSupportedException {
People c1 = new People("Tom",22,new Address("山东"));
Object c2 = c1.clone();
System.out.println(c2.toString());
c1.setAge(33);
c1.getAddress().setProvince("北京");
// Object c3 = c1.clone();
System.out.println(c2.toString());
// System.out.println(c3.toString());
}
}
结果
People{name='Tom', age=22, address=Address{province='山东'}}
People{name='Tom', age=22, address=Address{province='山东'}}

浙公网安备 33010602011771号