一起学习java中的"克隆"知识
理解克隆
克隆包括浅克隆与深克隆.
浅克隆就是复制对象时,仅仅复制对象本身(包括对象的基本成员变量),而不复制对象包含的引用指向的对象.
深克隆不仅复制对象本身,而且复制对象包含的引用指向的所有对象.
自定义类实现克隆
自定义类实现”克隆”的步骤如下:
- 自定义类实现Cloneable接口.这是一个标记性接口,实现该接口的对象可以实现”自我克隆”,接口里没有定义任何方法.
- 自定义类实现自己的clone()方法.该方法用于帮助其他对象来实现”自我克隆”,所谓”自我克隆”就是得到一个当前对象的副本,而且二者之间完全隔离.由于Object类提供的clone()方法使用了protected修饰,因此该方法只能被子类重写或调用.
- 实现clone()方法时,通过super.clone()调用Object实现的clone()方法来得到该对象的副本,并返回该副本.
如下程序可以让我们更加深入的理解克隆!
浅克隆程序如下:
package seven.three;
import java.util.Arrays;
/**
* 实现自我克隆<br>
* 2019年11月30日 上午8:46:02
*
* @author zcf
* @version 1.0
*/
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);// <1>
// 判断u1,u2的address是否相同
System.out.println(u1.address == u2.address);// <2>
}
}
/**
* 用户类<br>
* 2019年12月4日 下午8:01:02
* @author zcf
* @version 1.0
*/
class User implements Cloneable {
int age;
Address address;
/**
* @param age 年龄
* @param address 地址
*/
public User(int age) {
super();
this.age = age;
this.address = new Address("商水县");
}
/**
* 浅克隆
*/
public User clone() throws CloneNotSupportedException {
return (User) super.clone();
}
}
/**
* 地址类<br>
* 2019年12月4日 下午8:02:47
* @author zcf
* @version 1.0
*/
class Address {
/**
* 地址详情
*/
String detail;
/**
* 有参构造器
* @param detail 地址详情
*/
public Address(String detail) {
super();
this.detail = detail;
}
}
运行结果:
false
true
以上浅克隆程序在<1>处代码判断原有的User对象与克隆出来的User对象是否相同,程序返回false.
因为Object类提供的Clone机制只对对象里各实例变量进行”简单复制”,如果实例变量的类型是引用类型,Object的Clone机制也只是简单的复制这个引用变量,这样原有对象的引用类型的实例变量与克隆对象的引用类型的实例变量依然指向内存中的同一个实例,所以上面程序中<2>处代码输出true.
深克隆程序如下:
package seven.three;
import java.util.Arrays;
/**
* 实现自我克隆<br>
* 2019年11月30日 上午8:46:02
*
* @author zcf
* @version 1.0
*/
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);// <1>
// u1,u2的address不同,二者已完全隔离,即实现深克隆
System.out.println(u1.address == u2.address);// <2>
}
}
/**
* 用户类<br>
* 2019年12月4日 下午8:01:02
*
* @author zcf
* @version 1.0
*/
class User implements Cloneable {
int age;
Address address;
/**
* @param age 年龄
* @param address 地址
*/
public User(int age) {
super();
this.age = age;
this.address = new Address("商水县");
}
/**
* 深克隆
*/
public User clone() throws CloneNotSupportedException {
// 以下两行代码实现深克隆
User user = (User) super.clone();
user.address = (Address) user.address.clone();
return user;
}
}
/**
* 地址类<br>
* 2019年12月4日 下午8:02:47
*
* @author zcf
* @version 1.0
*/
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();
}
}
运行结果:
false
false
以上深克隆程序在<1>处代码判断原有的User对象与克隆出来的User对象是否相同,程序返回false.
<2>处代码判断u1,u2的address是否相同,返回false. u1,u2的address不同,二者已完全隔离,即实现深克隆.
彻底理解以上内容,就可以学会克隆了!