Object 类的 clone方法执行特定的克隆操作。首先,如果此对象的类不能实现接口 Cloneable,则会抛出 CloneNotSupportedException。(注意:所有的数组都被视为实现接口 Cloneable)否则,此方法会创建此对象的类的一个新实例,并像通过分配,严格使用此对象相应字段的内容初始化该对象的所有字段;这些字段的内容没有被自我克隆。所以,此方法执行的是该对象的“浅表复制”,而不“深层复制”操作。Object 类本身不实现接口 Cloneable,所以在类为 Object的对象上调用 clone 方法将会导致在运行时抛出异常。 下面从三个复制的实例代码来看它们之间的区别,我们需建立Person类:
public class Person{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void display() {
System.out.println("Name:" + name + "/tAge:" + age);
}
}
一、普通复制即我们最容易想到的将一个对象赋值给另外一个对象。
public static void main(String[] args) {
Person p1=new Person("jack",20);
Person p2=p1;
p1.setAge(49);//简单复制 p2.display(); p1.display(); System.out.println(p1); System.out.println(p2); }
结果: Name:jack Age:49 Name:jack Age:49 net.pcedu.clone.Person@c17164 net.pcedu.clone.Person@c17164
说明p1和p2对象的是同一个引用,所以再改属性2个都是改变的。
二、浅拷贝浅拷贝必需对Book类实现Cloneable接口的clone方法
public class Book implements Cloneable{
String bookName;
double price;
Person author;
public Book(String bn,double price,Person author){
bookName = bn;
this.price = price;
this.author = author;
}
public Object clone(){
Book b = null;
try{
b = (Book)super.clone();
}catch(CloneNotSupportedExceptione){
e.printStackTrace();
}
return b;
}
public void display(){
System.out.print(bookName + "/t" +price + "/t") ;
author.display();
}
}
publicstatic void main(Stringargs[]){
Book b1 = new Book("Java编程",30.50,new Person("张三",34));
Book b2 = (Book)b1.clone();
b2.price = 44.0;
b2.author.setAge(45);
b2.author.setName("李四");
b2.bookName = "Java开发";
b1.display();
b2.display();
}结果:Java编程 30.5 Name:李四 Age:45Java开发 44.0 Name:李四 Age:45说明p1和p2是不同的对象,但是p1对象的属性值也拷贝到p2中去了。 问题如下: 发现在改变b2的author对象属性时b1的author对象的属性也改变了,说明在浅拷贝中的author这个对象没有被完全拷贝,而是使用同一引用,这样就要使用深拷贝了。 三、深拷贝为了解决如上问题,我们需要用到深拷贝,其实很简单在拷贝book对象的时候加入如下语句 b.author =(Person)author.clone(); //将Person对象进行拷贝,Person对象需进行了拷贝 在运行上面的main方法,结果如下: Java编程30.5 Name:张三 Age:34Java开发44.0 Name:李四 Age:45说明p1和p2是不同的对象,但是p1对象的属性值也拷贝到p2中去了(含引用对象属性的拷贝)。 |