目录

1.什么是克隆对象?

2.为什么要使用克隆对象?

3.克隆对象的使用?

3.1 浅克隆

         3.2 深克隆


1.什么是克隆对象?

克隆这个词大家并不陌生,实质就是拷贝对象,形成一个对象的副本。克隆对象就是对已有的一个对象进行拷贝。

进行克隆的目的(意义):被克隆和克隆对象之间完全复制、相互之间没有影响的目的。

 

2.为什么要使用克隆对象?

 在java中,我们使用对象的时候直接去new一个对象就好了,为什么还要克隆对象呢?

       当我们new一个对象之后是要对该对象进行初始化的,不然这个对象是空的没有内容。而使用克隆,则会得到一个原对象以及原对象里面包含的内容。例如,你有一个User对象,里面的包含了相关的属性。此时你想要修改里面的某一属性,但又不想破坏原对象里面的数据,此时就可以克隆User这个对象,然后在克隆的这个User对象上进行修改操作。除此,如果你在操作完之后判断一下属性是否更改成功,则使用克隆的对象和原对象做一下对比即可。
 

3.克隆对象的使用?

3.1 浅克隆

       浅克隆就是把原对象中的一些属性值克隆过来。使用clone()方法进行浅克隆。但注意:必须要在被克隆类上实现Cloneable接口,并重写clone方法。若不没有实现该接口,则会抛出CloneNotSupportedException异常!
 

public class CloneTest1 {
	public static void main(String[] args) throws Exception {
		//创建原对象,并为原对象中的属性进行赋值,然后打印出结果
		User user = new User();
		user.setName("张三");
		user.setAge(18);
		System.out.println("原对象(user)的属性值:");
		System.out.println("姓名为:"+user.getName()+",年龄为:"+user.getAge());
		
		//对user对象进行克隆
		User user1 = (User) user.clone();
		//查看一下克隆对象中的属性值
		System.out.println("克隆后user1对象中的属性值:");
		System.out.println("姓名为:"+user1.getName()+",年龄为:"+user1.getAge()); //结果和原对象中属性值相同
 
		//对user1对象进行修改
		user1.setName("李四");
		//查看修改后的结果
		System.out.println("user1对象进行修改后的属性值:");
		System.out.println("姓名为:"+user1.getName()+",年龄为:"+user1.getAge()); //结果和原对象中属性值相同
	}
 
}
 
//定义一个User类
//实现Cloneable 接口
class User implements Cloneable {
	private String name;
	private int age;
	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;
	}
	
	//重写clone方法
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
	
	
}

测试结果为:

Java 克隆类 java中克隆对象_ci

从结果上可以看出,克隆对象user1和原对象user在修改属性数据时,两个对象之间的数据互不受影响。

       那么如果后期需要调整代码,需要在原有的user对象中添加一个引用类型Address字段,那么克隆的user1对象会能受到影响吗?能和原对象user中的数据一致吗?

看下面代码演示,在原有基础代码上加入一个Address的类,并分别在User类和Address类中加入重写Object的方法。注意:User类中的引用address字段的权限修饰符为public,否则无法运行! 

public class CloneTest1 {
	public static void main(String[] args) throws Exception {
		//创建原对象,并为原对象中的属性进行赋值,然后打印出结果
		Address address = new Address("中国","山东");
		User user = new User("张三",18,address);
		System.out.println("原对象(user)的属性值:");
		System.out.println("姓名为:"+user.getName()+",年龄为:"+user.getAge()+",地址为:"+user.address);
		
		//对user对象进行克隆
		User user1 = (User) user.clone();
		//查看一下克隆对象中的属性值
		System.out.println("克隆后user1对象中的属性值:");
		System.out.println("姓名为:"+user1.getName()+",年龄为:"+user1.getAge()+",地址为:"+user.address); //结果和原对象中属性值相同
		//对user对象进行修改
		user1.setName("李四");
		user1.getAddress().setCity("北京");
		//查看修改后的结果
		System.out.println("user1对象进行修改后的属性值:");
		System.out.println("姓名为:"+user1.getName()+",年龄为:"+user1.getAge()+",地址为:"+user1.address); //结果和原对象中属性值相同
		System.out.println("姓名为:"+user.getName()+",年龄为:"+user.getAge()+",地址为:"+user.address);
	}
 
}
 
//定义一个User类
class User implements Cloneable {
	private String name;
	private int age;
	public Address address; 
	public Address getAddress() {
		return address;
	}
	public void setAddress(Address address) {
		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;
	}
	
	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + ", address=" + address + "]";
	}
	public User(String name,int age,Address address) {
		super();
		this.name = name;
		this.age = age;
		this.address = address;
	}
	//重写clone方法
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
}
 
//定义一个address类
class Address{
	private String country;
	private String city;
	public String getCountry() {
		return country;
	}
	public void setCountry(String country) {
		this.country = country;
	}
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	@Override
	public String toString() {
		return "Address [country=" + country + ", city=" + city + "]";
	}
	public Address(String country,String city) {
		super();
		this.country = country;
		this.city = city;
	}
	
}

打印其结果为:

Java 克隆类 java中克隆对象_java_02

浅克隆只是克隆原对象中的引用类型指向,并非克隆了原对象中的全部数据。
 

3.2 深克隆

       深克隆和浅克隆的区别在于:浅克隆只克隆了原对象的引用类型的指向。深克隆则是克隆了原对象的所有。也就是说像上面案例所示,如果使两个对象之间互不影响,则使用深克隆。

       深克隆的使用:在引用类型所在的类使其实现Cloneable接口,并使用public修饰符重写Clone()方法。

代码如下:

在Address类中进项代码修改: 

class Address implements Cloneable{ //实现Cloneable接口
	private String country;
	private String city;
	public String getCountry() {
		return country;
	}
	public void setCountry(String country) {
		this.country = country;
	}
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	@Override
	public String toString() {
		return "Address [country=" + country + ", city=" + city + "]";
	}
	public Address(String country,String city) {
		super();
		this.country = country;
		this.city = city;
	}
	//重写clone()方法,并使用public修饰符
	public Object clone() throws CloneNotSupportedException {
		return super.clone();
	}

打印其结果为:

Java 克隆类 java中克隆对象_Java 克隆类_03

从结果上看原对象不会因为克隆对象的改变而改变了。做到了完全拷贝,但互不影响的目的。