我有2个列表,并且对于将对象添加到这两个列表中有点困惑:
TestClass e;
List lst1;
LinkedList lst2;
...
lst1.add(e);
lst2.add(e);
lst1
和lst2
会有e
的副本吗?或对同一对象e
的引用?
如果第一个为真,那么如果e
不可克隆,代码如何制作TestClass
的副本?
答案 0 :(得分:2)
他们将有相同的参考。如果您希望它是2个不同的属性,则必须手动复制值。
答案 1 :(得分:2)
第二个是真的:两个集合都将保存对同一个对象的引用。
答案 2 :(得分:1)
lst1
和lst2
会有e
的副本吗?
是强>
两个列表都将包含e
中包含的值的副本。 (请注意,e
包含引用,而不是实际对象。)
这意味着
两个列表都会对TestClass
e
引用的add
对象的每个引用都有一个副本。
从两个列表引用中都可以看到对TestClass
对象的更改。
添加后执行e = null
不会影响列表内容(列表包含副本,还记得吗?; - )
答案 3 :(得分:0)
这可以追溯到通过引用传递vs传递值的旧问题......
请参阅此stackoverflow question
lst1
和lst2
都将包含一个值(由变量e
表示),它将告诉JVM如何在堆内存中找到TestClass
实例。如果您通过e
,lst1
或lst2
访问实例(只有一个实例),则更改将随处可见!
更改此行为的唯一方法是覆盖Object clone()
函数中的TestClass
并将e.clone()
传递给add(...)
函数。请参阅documentation
如果由于任何原因无法修改TestClass
,您也可以自己克隆实例(基本上是在clone()
之外实施TestClass
)。使用TestClass
运算符创建一个新的e2
实例new
,然后从{{1}获取其实例变量(小心它包含其他自定义对象) }通过它的'getters'并通过'setter'将值设置为e
。这很丑陋,我希望你拒绝这样做......