嗨我被问到这个面试问题,你有一个不可变类中的对象列表,该类是否真的可以修改,可以修改什么以及如何防止它。我给出了以下解决方案。
public final class A{
final List<B> listOfB; // B is mutable
public List<B> getListOfB(){
return Collections.unmodifiableList(this.listOfB);
}
}
现在他说,即使在获得getListOfB()之后,他也可以改变&#39; B&#39;实例,并希望我也避免这种情况。然后我说。
public List<B> getListOfB(){
List<B> ret;
for(B b: this.listOfB){
ret.add(b.clone()); // basically make a deep copy of 'b' for return list
}
return ret;
}
面试官没有回复任何说这是对或错的事。
这个解决方案肯定有效。但有没有更好的方法,我的方法非常笨拙,需要额外的内存。
PS:假设B不能成为不可变的。
答案 0 :(得分:2)
假设B
是接口或接口A
的实现,您可以使用listOfB
java.net.Proxy
或B
来包装A
的每个元素。 UnsupportedOperationException
分别通过抛出listOfB
拦截所有修改调用。
更详细,用java.net.Proxy
包装的实例替换A
的每个项目,实现listOfB
。然后,每当有人抓取UnsupportedOperationException
的项目时,他将获得包装的实例。每当有人在这样一个包裹的项目上调用一个setter时,拦截该调用并抛出一个Collections.unmodifiableXXX()
。希望你知道我的意思。它基本上是listOfB
的作用。如果您了解可能修改B
项的状态的所有方法,则POJO
不必是{{1}}。只需确保您的包装器通过抛出异常来替换所有修改方法。