今天写一个很简单的背包数据结构的实现,却被一个小问题难住了。在add一个新元素的方法中,开始时我是这么写的:
可是这是一种很不安全的写法。比如客户想把一个newEntry对象添加到两个背包中,那么这两个背包中的对象实际上是同一个对象。因此在add方法中最好能复制一份newEntry, 把让entry[size]引用newEntry的备份。
而newEntry是Object 类型,不能直接调用newEntry.clone()返回一个备份。怎么办呢?在网上搜啊搜,才知道我的疑问来自于浅复制和深复制的概念及实现。有一篇文章已经说得很好了:Java中的深复制与浅复制 http://java.chinaitlab.com/oop/716567.html 。下面总结一下该文章的内容以及我的理解。
浅复制就是引用不同而对象相同,深复制就是对象也不同。clone() 方法十分诡异,一个类要implements Clonable, 然后覆盖clone() 方法,在clone() 方法中调用super.clone(), 才能实现深复制。如果不实现Clonable接口,则仍然是浅复制。我认为此方法很麻烦,比如我想复制一个类对象,就得把这个类的所有域的类、域的类的域的类...都搞成Clonable。更重要的是,这个方法解决不了当前的问题:我要复制一个Object。
另一种深复制的方法是利用“序列化”。把对象写到一个Byte流中,再读出来,达到复制的效果:
啊哈,其实一个Object不就是一堆字节流吗,类的结构决定了“划分”字节流的方式,从而成了某个类的对象。
通过这次折腾,发现自己Java学得太菜了,对引用的认识太浅。要走的路还很长,继续折腾吧!