Java基础篇——深克隆与浅克隆

基本定义

克隆,顾名思义,即是产生一个与原对象“完全”一样的一个新对象。这里的一样,或许是表面的一样,或许是真的一样。这就牵扯到两个新定义:浅克隆与深克隆。

浅克隆:新对象的基础类型的变量值与原对象相同,而特殊对象,即非八大基本类型的对象与原对象指向同一内存空间,不管新老对象谁对这段空间进行操作都会影响到另一个,就像又要让钱钟书讲三字经又要他讲陶渊明,一人难敌两角,肯定会引起问题,“假克隆”。

深克隆:新对象除了与老对象的八大基本类型的赋值一致以外,其类类型的对象在保证赋值一致的基础上,指向的是一段新的内存空间,就像把同一斤大五花克隆两份,一个给A厨师,一个给B厨师,你要东坡还是红烧随你便,最后出来的是完全不同的两道菜,“真克隆”。

实现方式

1.将该类实现clonable接口;

2.并覆盖Object的clone方法,设置为public关键字,原方法为protected;

3.在clone()中调用super.clone();

4.或者使用你的脑力自己实现一个克隆;

原理实现

1.深克隆

public class MecClone implements Serializable {
	private static final long serialVersionUID = 7511752675823078486L;
	
	public MecClone() {
	}
	
	private static void deleteResultObj(String path) {
		File file = new File(path);
		if(!file.isFile() || !file.exists()) {
			System.out.println("删除" + path + "文件失败.....");
			return;
		}
		
		Boolean deleteSuccess = file.delete();
		if(deleteSuccess) {
			System.out.println("删除" + path + "文件成功!");
			return;
		} else {
			System.out.println("删除" + path + "文件失败......");
                        return;
		}
	}
	
	// TODO 简便浅克隆的实现 未完成

	
	public Object deepClone(Object object) {
		Object result = null;
		try {
			ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("result.obj"));
			out.writeObject(object);
			out.close();
			
			ObjectInputStream in = new ObjectInputStream(new FileInputStream("result.obj"));
			result = in.readObject();
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		if(result == null) System.out.println("复制失败!");
		deleteResultObj("result.obj");
		
		return result;
	}
}

原理:首先将需要复制的对象进行序列化,并将保存着这个对象基本信息的文件保存至磁盘,之后使用反序列化将对象读取出来,并将文件删除。这样,由于反序列化时JVM要根据序列号读出类名、接口名、方法和属性等信息重新申请空间,指向的自然不是同一地址【此处可能有较大问题,欢迎大佬斧正】。Demo如下:

public class Demo {
	public static void main(String[] args) {
		MecClone mecClone = new MecClone();
		UserModel userOne = new UserModel().setName("pikachew").setPassword("pikapika").setAge("99");
		UserModel userTwo = (UserModel) mecClone.deepClone(userOne);
		userTwo.setName("Raychew").setPassword("rayray").setAge("88");
		
		System.out.println(userTwo);
		System.out.println(userOne);
	}
}
删除result.obj文件成功!
Raychew rayray 的年龄88
pikachew pikapika 的年龄99

2.浅克隆

可以简单的通过实现Clonable接口、覆盖clone()方法实现,此处不予演示。

发布了29 篇原创文章 · 获赞 0 · 访问量 3308

猜你喜欢

转载自blog.csdn.net/smithlaod/article/details/82915505