Java之clone()方法

clone()是Object类的protected 方法,只有实现了Cloneable接口的类,才可以调用clone()方法。

1.浅复制

Lover.java

package zh.clone.demo;

public class Lover {

	private String name;
	private int age;
	private char sex;
	
	public Lover() {
	
	}

	public Lover(String name, int age, char sex) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
	}

	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;
	}

	public char getSex() {
		return sex;
	}

	public void setSex(char sex) {
		this.sex = sex;
	}

	@Override
	public String toString() {
		return "Lover [name=" + name + ", age=" + age + ", sex=" + sex + "]";
	}

}

Person.java

package zh.clone.demo;

// 实现Cloneable接口
public class Person implements Cloneable{

	private String name;
	private int age;
	private char sex;
	private Lover lover;
	
	public Person() {

	}

	public Person(String name, int age, char sex, Lover lover) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
		this.lover = lover;
	}

	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;
	}

	public char getSex() {
		return sex;
	}

	public void setSex(char sex) {
		this.sex = sex;
	}

	public Lover getLover() {
		return lover;
	}

	public void setLover(Lover lover) {
		this.lover = lover;
	}

	// 重写clone(),权限修饰符改为public
	@Override
	public Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
	
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", sex=" + sex
				+ ", lover=" + lover + "]";
	}
	
}

CloneDemo1.java

package zh.clone.demo;

/*
 * 浅复制:只复制了基本数据类型和String类型的数据,并没有复制内部对象。
 * 因此,复制品修改基本数据类型和String类型的数据,不会影响原来对象对应的数据。
 * 但是,复制品修改内部对象的数据,会修改原来对象对应的数据。
 */
public class CloneDemo1 {

	public static void main(String[] args) throws Exception {
		
		Lover lover = new Lover("小龙女", 18, '女');
		Person person = new Person("杨过", 17, '男', lover);
		
		// person只有实现了Cloneable接口,才可以调用clone()
		Person personCopy = (Person) person.clone();
		
		System.out.println(personCopy);
		System.out.println(person);
		//Person [name=杨过, age=17, sex=男, lover=Lover [name=小龙女, age=18, sex=女]]
		//Person [name=杨过, age=17, sex=男, lover=Lover [name=小龙女, age=18, sex=女]]

		// personCopy修改"基本数据类型和String类型的数据",不会改变person对应的数据
		personCopy.setName("神雕大侠");
		personCopy.setAge(36);
		personCopy.setSex('M');
		System.out.println(personCopy);
		System.out.println(person);
		//Person [name=神雕大侠, age=36, sex=M, lover=Lover [name=小龙女, age=18, sex=女]]
		//Person [name=杨过, age=17, sex=男, lover=Lover [name=小龙女, age=18, sex=女]]
		
		// personCopy修改"内部对象的数据",会影响person对应的数据
		personCopy.getLover().setName("神仙姐姐");
		personCopy.getLover().setAge(37);
		personCopy.getLover().setSex('F');
		System.out.println(personCopy);
		System.out.println(person);
		//Person [name=神雕大侠, age=36, sex=M, lover=Lover [name=神仙姐姐, age=37, sex=F]]
		//Person [name=杨过, age=17, sex=男, lover=Lover [name=神仙姐姐, age=37, sex=F]]
		
	}
	
}

结论:浅复制不能达到复制品与原来对象完全分离的目的,复制品内部对象的变化,会引起原来对象相应的内部对象的变化。

2.深复制

Lover.java
package zh.clone.demo;

// 实现Cloneable接口
public class Lover implements Cloneable{

	private String name;
	private int age;
	private char sex;
	
	public Lover() {
	
	}

	public Lover(String name, int age, char sex) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
	}

	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;
	}

	public char getSex() {
		return sex;
	}

	public void setSex(char sex) {
		this.sex = sex;
	}

	// 重写clone(),权限修饰符改为public
	@Override
	public Lover clone() throws CloneNotSupportedException {
		return (Lover) super.clone();
	}
	
	@Override
	public String toString() {
		return "Lover [name=" + name + ", age=" + age + ", sex=" + sex + "]";
	}

}

Person.java

package zh.clone.demo;

// 实现Cloneable接口
public class Person implements Cloneable{

	private String name;
	private int age;
	private char sex;
	private Lover lover;
	
	public Person() {

	}

	public Person(String name, int age, char sex, Lover lover) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
		this.lover = lover;
	}

	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;
	}

	public char getSex() {
		return sex;
	}

	public void setSex(char sex) {
		this.sex = sex;
	}

	public Lover getLover() {
		return lover;
	}

	public void setLover(Lover lover) {
		this.lover = lover;
	}

	// 重写clone(),权限修饰符改为public
	@Override
	public Person clone() throws CloneNotSupportedException {
		Person personCopy = (Person) super.clone();
		// 实现深复制,则要对内部的每一个对象进行复制
		// this.getLover().clone():对原来对象的内部对象进行复制
		// 因此,要求原来对象的内部对象也要实现Cloneable接口
		personCopy.setLover(this.getLover().clone());
		return personCopy;
	}
	
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", sex=" + sex
				+ ", lover=" + lover + "]";
	}
	
}

CloneDemo2.java

package zh.clone.demo;

/*
 * 深复制:复制了原来对象的所有数据。
 * 复制品的任何改变,都不会影响原来对象的数据。
 */
public class CloneDemo2 {

	public static void main(String[] args) throws Exception {
		
		Lover lover = new Lover("小龙女", 18, '女');
		Person person = new Person("杨过", 17, '男', lover);
		
		// person只有实现了Cloneable接口,才可以调用clone()
		Person personCopy = (Person) person.clone();
		
		System.out.println(personCopy);
		System.out.println(person);
		//Person [name=杨过, age=17, sex=男, lover=Lover [name=小龙女, age=18, sex=女]]
		//Person [name=杨过, age=17, sex=男, lover=Lover [name=小龙女, age=18, sex=女]]

		// 修改基本数据类型和String类型的数据
		personCopy.setName("神雕大侠");
		personCopy.setAge(36);
		personCopy.setSex('M');
		// 修改内部对象的数据
		personCopy.getLover().setName("神仙姐姐");
		personCopy.getLover().setAge(37);
		personCopy.getLover().setSex('F');
		// 复制品的改变 完全不影响 原来对象
		System.out.println(personCopy);
		System.out.println(person);
		//Person [name=神雕大侠, age=36, sex=M, lover=Lover [name=神仙姐姐, age=37, sex=F]]
		//Person [name=杨过, age=17, sex=男, lover=Lover [name=小龙女, age=18, sex=女]]
		
	}
	
}

猜你喜欢

转载自blog.csdn.net/qq_41706150/article/details/80113629