最近写代码时遇到一个需要对对象进行深克隆的问题,由于自从学了之后就再也没有用过,导致都不记得怎么写了,于是乎又复习了一遍,可是还是没搞得太清楚,有时间再找个时间深度复习下。

以下是今天复习写的一个案例,总算是写出来了。做个记录。日后好在此基础上继续学习。

package com.noteshare.test;

import java.io.Serializable;
import java.util.ArrayList;

public class DepthClone {
	public static void main(String[] args) throws Exception {
		//创建学校
		School school = new School();
		school.setAge(100);
		school.setName("北大");
		ArrayList<Person> persons = new ArrayList<Person>();
		persons.add(new Person(100,"张三丰"));
		school.setPersons(persons);
		//克隆一个学校
		School schoolTemp = (School) school.clone();
		//修改学校名称
		schoolTemp.setAge(10);
		schoolTemp.setName("农大");
		ArrayList<Person> personTemp = schoolTemp.getPersons();
		for (Person person : personTemp) {
			person.setAge(10);
			person.setName("张无忌");
		}
		System.out.println(school.toString());
		System.out.println("-------------------------------------------");
		System.out.println(schoolTemp.toString());
	}
}

class School implements Cloneable,Serializable{
	/** 
	 */ 
	private static final long serialVersionUID = -4602658994466995471L;
	/**
	 * 学校年龄
	 */
	private int age;
	/**
	 * 学校名称
	 */
	private String name;
	/**
	 * 学校的人员
	 */
	ArrayList<Person> persons;

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public ArrayList<Person> getPersons() {
		return persons;
	}

	public void setPersons(ArrayList<Person> persons) {
		this.persons = persons;
	}

	@Override
	protected Object clone() throws CloneNotSupportedException {
		School school = null;
		school = (School) super.clone();
		school.persons = new ArrayList<>();
		for (Person person : persons) {
			person = (Person) person.clone();
			school.persons.add(person);
		}
		return school;
	}
	
	@Override
	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append(this.name).append("\n").append(age).append("\n");
		for (Person person : persons) {
			sb.append(person.getName()).append(":").append(person.getAge());
		}
		return sb.toString();
	}
}

class Person implements Cloneable,Serializable{
	/** 
	 */ 
	private static final long serialVersionUID = -6755560113988590616L;
	/**
	 * 年龄
	 */
	private int age;
	/**
	 * 姓名
	 */
	private String name;
	
	public Person(int age,String name) {
		this.age = age;
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
}
北大
100
张三丰:100
-------------------------------------------
农大
10
张无忌:10


以下是笔记补充:

时间:20160913

补充深度克隆和浅克隆的基本原理

Shallow Clone&Deep Clone
为什么会有深克隆和浅克隆这两个概念呢,这估计得从基本数据类型和引用类型来说起,我们知道基本数据类型如果对变量赋值的话直接是字面量赋值,而如果我们对对象类型或者说是引用类型赋值时,其实我们只是复制了引用,而实际上两个变量指向的对象是相同的。所以针对引用类型时如果你通过其中一个变量去该表对象的值的话,宁外一个变量指向的对象也是会改变的(其实是同一个对象),下面给出一个图来说明:

java中的深克隆和浅克隆

上图是一个浅克隆的图形

其中original和copy分别代表原对象和克隆后的对象,其中基本类型salary是进行了值的copy,两个对象中分别修改不会相互影响,

而String类型的name由于String是final的所以如果你分别对original和copy后的对象的name属性修改都会指向新的对象,而不会相

互影响。右上角那个图形应该是代表字符串池。而如果你尝试去修改hireDay的话,由于他们指向的是相同的date对象,如果你分别通过original或copy后的对象的hireDay变量去操作date的属性的话是会相互影响的因为他们指向的是同一个date对象。

package com.noteshare.test;

import java.util.Date;

public class DeepClone {
	@SuppressWarnings("deprecation")
	public static void main(String[] args) throws Exception {
		Demo demo1 = new Demo(10,"张三",new Date());
		Demo demo2 = (Demo) demo1.clone();
		demo2.getTime().setHours(5);
		demo2.setName("李四");
		//string是终态的索引从新赋值其实就是新的对象所以demo1和demo2指向的是不同的对象,字面量均来自字符串池
		System.out.println(demo1.getName());
		System.out.println(demo2.getName());
		//Date类型为引用类型克隆只是copy了引用,其实demo1和demo2的time指向的是同一个对象
		//所以操作demo2中time对象时demo1的time对象也跟着变
		System.out.println("----------------");
		System.out.println(demo1.getTime().getHours());
		System.out.println(demo2.getTime().getHours());
		//给demo1的time变量重新赋值让其指向新的对象,则此时demo1和demo2的time分别指向了不同的对象,所以此时如果再对它们
		//的time变量的对象进行修改时是不会相互影响的
		demo1.setTime(new Date());
		System.out.println("==============");
		System.out.println(demo1.getTime().getHours());
		System.out.println(demo2.getTime().getHours());
		demo1.getTime().setHours(8);
		System.out.println("==============");
		System.out.println(demo1.getTime().getHours());
		System.out.println(demo2.getTime().getHours());
		
	}
}

class Demo implements Cloneable{
	public Demo() {
	}
	public Demo(int age,String name,Date time) {
		this.age = age;
		this.name = name;
		this.time = time;
	}
	private int age;
	private String name;
	private Date time;
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Date getTime() {
		return time;
	}
	public void setTime(Date time) {
		this.time = time;
	}
	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
}





浏览 509 评论 0 赞 0 砸 0 标签: 面试题 笔试题 Java基础知识
评论
还可以再输入500个字

请您注意

·自觉遵守:爱国、守法、自律、真实、文明的原则
·尊重网上道德,遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他各项有关法律法规
·严禁发表危害国家安全,破坏民族团结、国家宗教政策和社会稳定,含侮辱、诽谤、教唆、淫秽等内容的作品
·承担一切因您的行为而直接或间接导致的民事或刑事法律责任
·您在NoteShare上发表的作品,NoteShare有权在网站内保留、转载、引用或者删除
·参与本评论即表明您已经阅读并接受上述条款