java深度复制实用程序如何保留对象';内在关系?

java深度复制实用程序如何保留对象';内在关系?,java,deep-copy,Java,Deep Copy,我使用apacheSerializationUtils深度复制对象,发现了一些惊人的东西。例如,对象A有两个成员B1,B2,它们都有相同的成员C(引用相同的对象)。 深度复制之后,创建了A',我希望B1'有成员C1',B2'有成员C2'。但是,B1'和B2'都有相同的成员C' 似乎在深度复制之后,对象层次结构和关系得到了维护。这是如何实现的?我不知道Apache库,但很可能它保存了迄今为止复制的实例的映射。如果遇到要复制的实例C,它首先检查该实例是否已经存在副本C'。如果是,则使用现有副本。如果

我使用apache
SerializationUtils
深度复制对象,发现了一些惊人的东西。例如,对象
A
有两个成员
B1
B2
,它们都有相同的成员
C
引用相同的对象)。 深度复制之后,创建了
A'
,我希望
B1'
有成员
C1'
B2'
有成员
C2'
。但是,
B1'
B2'
都有相同的成员
C'


似乎在深度复制之后,对象层次结构和关系得到了维护。这是如何实现的?

我不知道Apache库,但很可能它保存了迄今为止复制的实例的映射。如果遇到要复制的实例
C
,它首先检查该实例是否已经存在副本
C'
。如果是,则使用现有副本。如果没有,它将创建
C
的深度副本,给出
C'
,并将该副本存储在地图中


需要考虑的一个要点是:我想Apache基于
=
操作符而不是
equals()
方法进行存在性测试,因为
=
操作符将给出最干净的结果,最类似于原始引用结构。如果不是,恰好满足
equals()
测试的两个不同的实例
C1
C2
将作为单个副本
C'

我不知道Apache库,但很可能它保存了迄今为止复制的实例的映射。如果遇到要复制的实例
C
,它首先检查该实例是否已经存在副本
C'
。如果是,则使用现有副本。如果没有,它将创建
C
的深度副本,给出
C'
,并将该副本存储在地图中


需要考虑的一个要点是:我想Apache基于
=
操作符而不是
equals()
方法进行存在性测试,因为
=
操作符将给出最干净的结果,最类似于原始引用结构。如果不是,则两个不同的实例<代码> C1和 C2正好满足 >代码>(/Cult>),测试将作为一个单一的拷贝<代码> C′< /COD>。

如果两个引用指向同一个对象,那么我们可以考虑两个引用具有相同的标识。也就是说,考虑到:

Object a = ...;
Object b = ...;
如果保持不变,
a
b
是“相同的”:
a==b
,只有当它们指向同一对象时才会保持不变

注意
a.equals(b)
是不同的;适用的任何两个引用都可以被视为“相等”,但可能涉及两个对象。简单的例子:

String a = new String("Hello");
String b = new String("Hello");
a == b; // this is false
a.equals(b); // this is true
可以确定两个参考是否相同,而不仅仅是相等

一个简单的检查就是我刚才给你们看的:
=
,它检查相同的和不相等的

最有可能的是,SerializationUnits中的代码使用的是一个映射到标识(或多或少是“指针”)的映射。WHM主要是一个内部实现,但请注意,您始终可以通过
System.identityHashCode
获取标识hashcode,它为同一对象返回相同的值,即使该对象发生了变化。理论上,
a.hashCode()
可以返回不同的值(对于可变对象,它往往会返回不同的值),但是
System.identityHashCode(a)
对于VM生命周期内的任何给定实例都是相同的值

纯简
HashMap
使用
a.hashCode()
知道要查看哪个bucket,然后
a.equals(b)
扫描相等性

A
WeakHashMap
使用
System.identityHashCode(A)
知道要查看哪个bucket,然后
A==b
扫描是否相等

有了这些,编写一个保留层次结构和关系的序列化程序就变得微不足道了

还要注意的是,如果没有这样的机制,固态序列化是不可能的。毕竟,想象一下这种结构:

List<Object> list = new ArrayList<Object>();
list.add(list); // ooooh, recursion!
List List=new ArrayList();
列表。添加(列表);//哦,递归!

<> >没有工具如<代码> WeakHashMap < /代码>,任何试图序列化这个构造的结果都会导致< <代码> StackOverflowError >代码>,原因显而易见。

如果两个引用指向同一个对象,让我们把两个引用看作“同一个身份”。也就是说,考虑到:

Object a = ...;
Object b = ...;
如果保持不变,
a
b
是“相同的”:
a==b
,只有当它们指向同一对象时才会保持不变

注意
a.equals(b)
是不同的;适用的任何两个引用都可以被视为“相等”,但可能涉及两个对象。简单的例子:

String a = new String("Hello");
String b = new String("Hello");
a == b; // this is false
a.equals(b); // this is true
可以确定两个参考是否相同,而不仅仅是相等

一个简单的检查就是我刚才给你们看的:
=
,它检查相同的和不相等的

最有可能的是,SerializationUnits中的代码使用的是一个映射到标识(或多或少是“指针”)的映射。WHM主要是一个内部实现,但请注意,您始终可以通过
System.identityHashCode
获取标识hashcode,它为同一对象返回相同的值,即使该对象发生了变化。理论上,
a.hashCode()
可以返回不同的值(对于可变对象,它往往会返回不同的值),但是
System.identityHashCode(a)
对于VM生命周期内的任何给定实例都是相同的值

纯简
HashMap
使用
a.hashCode()
知道要查看哪个bucket,然后
a.equals(b)
扫描相等性

A
WeakHashMap
使用
System.identityHashCode(A)
知道要查看哪个bucket,然后
A==b
扫描是否相等

有了它,编写一个序列化程序