“假设您正在向一个方法传递或返回一个对可变对象的引用数组。仅仅制作一个引用副本是否安全?制作一个浅拷贝是否安全?”
这是给我班级的一个研究问题,答案是“两者都不安全。在这种情况下,只有深层复制是安全的。”
为什么是这样?
“安全”可能意味着许多事情,但在您的特定上下文中,它是关于“您的”私有数据的安全性(文本将“您”称为某些Java类的编写者)。如果您让班级的客户端访问并在您的背后进行修改,则您的私人数据可能不安全。
因此:
实际上,所有这些都是很多CPU工作并占用内存,所以很少这样做。你要么设计一切都是不可变的,要么就是生活在可变对象固有的危险之中。
如果您的对象是可变的,则意味着任何引用它们的客户端都可以修改它们。这可能导致竞争条件,死锁和其他无趣的行为。但是,如果在使用对象之前对其进行了深层复制,则可以有效地处理对象的快照。这可确保没有其他客户端能够修改它们,从而消除任何并发或正确性问题。
在第一种情况下,可以修改原始数组元素和对象。在第二种情况下,只能修改对象,因为我们不再能够访问原始数组。如果你执行深层复制,我们正在使用完全不同的数组和对象,所以当然它是安全的。