基本定义
克隆,顾名思义,即是产生一个与原对象“完全”一样的一个新对象。这里的一样,或许是表面的一样,或许是真的一样。这就牵扯到两个新定义:浅克隆与深克隆。
浅克隆:新对象的基础类型的变量值与原对象相同,而特殊对象,即非八大基本类型的对象与原对象指向同一内存空间,不管新老对象谁对这段空间进行操作都会影响到另一个,就像又要让钱钟书讲三字经又要他讲陶渊明,一人难敌两角,肯定会引起问题,“假克隆”。
深克隆:新对象除了与老对象的八大基本类型的赋值一致以外,其类类型的对象在保证赋值一致的基础上,指向的是一段新的内存空间,就像把同一斤大五花克隆两份,一个给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()方法实现,此处不予演示。