JAVA对象之克隆-原理分析

来源:互联网 发布:微信点赞软件下载 编辑:程序博客网 时间:2024/06/06 06:39

JAVA对象之克隆

 

  对象的复制可以说是非常普遍的一个问题,当然也是需要注意的一个问题,最简单的就是,从数据库中查询出一个对象,然后想在内存中修改这个对象的值,返回给用户,但是如果你修改对象的代码块还是session的管控范围之内,像hibernate这些ORM框架,则会自动将你修改的内容更新到数据库。这个时候我们本身是不愿意让修改的对象复制到数据库去的,此时采用对象的克隆就是一个很好的例子

对象的克隆要注意三个地方:

1.为该类实现Cloneable接口

2.在类中实现public访问权限的clone()方法

3.在类的clone方法中调用顶级父类Object的clone方法

为什么要实现这三步?

1.为啥要实现Cloneable方法?

这里主要考虑两方面,(1),当一个类继承自基类,类本身具有clone能力时,但是基类不具有clone能力,此时我们上溯造型时,就不知道这个类是否具有clone能力了,因为这个基类可能还有其他实现类并没有clone能力,所以此时就可以采用 对象 instanceof Cloneable来判断该对象是否真的具有clone能力。

(2)JVM不希望所有的类都具有clone能力,因此在调用对象的clone方法时,都需要先校验该对象是否真的具有Clone能力。没有的则会抛出 CloneNotSupportedException

因此想要clone的类必须实现Cloneable这个接口

2.顶级类Object的clone方法是protected的,因此想要外部可以访问clone方法就必须为clone类实现public访问域的方法。

3.在实现类的clone方法中调用super.clone()

因为Object类会根据当前需要clone的对象计算出该对象的内存大小,然后按照位进行复制,因此真正的复制在Object对象中发生的

这就是这三步骤必须要的原因

当一个对象中具有其他对象句柄时,此时的复制能否将句柄的数据也一并复制呢?

答案是否定的

复制的对象只会复制当前对象的内容,并不会复制句柄指向的内存的内容

这里我觉得有两个原因:

1.对象中包含的其他对象句柄所属的类本身不一定具备复制能力

2.复制句柄中的类会成为一张对象网,这可能这并不是开发者的初衷

 

因此如果要为对象中的每个句柄进行clone的话,需要在clone方法中调用每个句柄的clone方法这样才能获得句柄的clone,以此类推,才能获得所有的clone

如果想要对一个对象网进行clone,而且对象网又非常庞大,涉及到几百个类,此时如果按照这种方式进行深层次clone的话,则无疑是

意见非常痛苦的事情

有没有办法进行简单的深层次clone呢?

答案是有的

采用对象的序列化技术进行clone,对象的序列化会将对象以及对象的句柄的内容都序列化,然后输出到对象的流中,可以将流直接保存到内存二级制流中

然后再用对象输入流从内存二进制中读取该流,再转换成相应的对象,这样就完成了非常复杂而且是深层次的复制。可以恢复出一个巨大的对象网.

 

 

欢饮拍砖

 

 

 

 

0 0
原创粉丝点击