自定义实现克隆
java提供了一个protected修饰的clone(),方法,该方法用于帮助其他对象实现实现自我克隆,就是得到一个对象的副本,而且二者之间完全分离,由于Object方法使用了protected修饰,因此此方法只能被子类重写或调用.
自定义实现克隆步骤如下
1.自定义实现Cloneable接口.这是一个标记性接口,实现该接口的对象可以实现"自我克隆",接口里面没有定义任何方法
2.自定义实现Clone()方法
3.实现clone()方法
3.实现Clone()方法时通过super.clone()调用Object实现clone()方法来得到该对象的副本,定返回该对象的副本.
下面程序示范如何实现"浅克隆"
public class CloneTest {
/**
* @param args
* @throws CloneNotSupportedException
*/
public static void main(String[] args) throws CloneNotSupportedException {
// TODO Auto-generated method stub
User u1 = new User(28);
// clone得到u1对象的副本
User u2 = u1.clone();
// 判断u1,u2是否相同
System.out.println(u1 == u2);// ①
// 判断u1,u2的address是否相同
System.out.println(u1.address == u2.address);// ②
}
}
class User implements Cloneable {
int age;
Address address;
/**
* @param age
* @param address
*/
public User(int age) {
super();
this.age = age;
this.address = new Address("商水县");
}
// 通过super.clone()来实现clone方法
public User clone() throws CloneNotSupportedException {
return (User) super.clone();
}
}
class Address {
String detail;
/**
* @param detail
*/
public Address(String detail) {
super();
this.detail = detail;
}
}
①号代码处因为两个对象不相等返回false.
false
②号代码处返回true,被克隆出来的u2对象所引用的地址没有改变所以返回true
true
深克隆不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象.
下面根据上面式列改写深克隆
public class CloneTest {
/**
* @param args
* @throws CloneNotSupportedException
*/
public static void main(String[] args) throws CloneNotSupportedException {
// TODO Auto-generated method stub
User u1 = new User(28);
// clone得到u1对象的副本
User u2 = u1.clone();
// 此处输出false,说明深克隆成功
System.out.println(u1.address == u2.address);
}
}
class User implements Cloneable {
int age;
Address address;
/**
* @param age
* @param address
*/
public User(int age) {
super();
this.age = age;
this.address = new Address("商水县");
}
// 通过super.clone()来实现clone方法
public User clone() throws CloneNotSupportedException {
// 克隆当前对象
User u1 = (User)super.clone();
// 对当前对象所引用的地址进行克隆
u1.address = u1.address.clone();
// 把克隆的对象返回出去
return u1;
}
}
class Address implements Cloneable {
String detail;
/**
* @param detail
*/
public Address(String detail) {
super();
this.detail = detail;
}
public Address clone() throws CloneNotSupportedException {
return (Address) super.clone();
}
}