java-clone

在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,AB是两个独立的对象,但B的初始值是由A对象确定的。

要满足这种需求虽然有很多途径,但实现clone()方法是其中最简单,也是最高效的手段。

 

class Person implements Cloneable {

private String name;

private int age;

private Address address;

private List<Address> addresss;

 

public Person() {

}

 

public Person(String name, int age,Address address,List<Address> addresss){

this.name = name;

this.age = age;

this.address=address;

this.addresss=addresss;

}

 

public Address getAddress() {

return address;

}

 

public void setAddress(Address address) {

this.address = address;

}


public List<Address> getAddresss() {

return addresss;

}

 

public void setAddresss(List<Address> addresss) {

this.addresss = addresss;

}

 

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;

}

 

@Override

protected Object clone() throws CloneNotSupportedException {

 

Person person= null;

try {

person =(Person) super.clone();

if(person.address!=null)

person.address=(Address) this.address.clone();

List<Address> temp=new ArrayList<Address>(

for(Address add :this.addresss){

temp.add((Address) add.clone());

}

person.addresss=temp;


catch (CloneNotSupportedException e) {

e.printStackTrace();

}

return person;

}

 

@Override

public String toString() {

return "Person [address=" + address + ", addresss=" + addresss

", age=" + age + ", name=" + name + "]";

}

}

 

class Address implements Cloneable{

String id;

 

public Address() {

}

public Address(String id) {

this.id=id;

}

 


public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}


@Override

protected Object clone() {

Object obj= null;

try {

System.out.println(super.getClass());

obj =super.clone();


catch (CloneNotSupportedException e) {

e.printStackTrace();

}

return obj;

}

@Override

public String toString() {

return "Address [id=" + id + "]";

}



}

 

 

public class Test{

public static void main(String[] args) throws CloneNotSupportedException {


Address address = new Address("0");

Address address1 = new Address("1");

Address address2 = new Address("2");

Address address3 = new Address("3");

List<Address> adds=new ArrayList<Address>();

adds.add(address1);

adds.add(address2);

adds.add(address3);

Person p1 = new Person("djz", 23,address,adds);


System.out.println(p1);

Person p2 = (Person) p1.clone();

System.out.println(p2);

// 不是同一个Person 对象.

System.out.println(p1 == p2);

// 修改p1 对象属性值,不影响 p2 对象的属性值.

p1.setAge(18);

p1.getAddress().setId("2");

List<Address> addresss = p1.getAddresss();

for (Address address4 : addresss) {

address4.setId("666");

}

System.out.println(p1);

System.out.println(p2);

 

}

}

 


clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象。所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象。那么在java语言中,有几种方式可以创建对象呢?

使用new操作符创建一个对象

使用clone方法复制一个对象

那么这两种方式有什么相同和不同呢? new操作符的本意是分配内存。程序执行到new操作符时, 首先去看new操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间。分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化,构造方法返回后,一个对象创建完毕,可以把他的引用(地址)发布到外部,在外部就可以使用这个引用操纵这个对象。而clone在第一步是和new相似的, 都是分配内存,调用clone方法时,分配的内存和源对象(即调用clone方法的对象)相同,然后再使用原对象中对应的各个域,填充新对象的域, 填充完成之后,clone方法返回,一个新的相同的对象被创建,同样可以把这个新对象的引用发布到外部。

猜你喜欢

转载自blog.csdn.net/qq_34665176/article/details/80225935