嗨,我被问到这个采访问题,您有一个不变类中的对象列表,该类真的是不可变的,可以修改什么以及如何防止它。我给出了以下解决方案。
public final class A{
final List<B> listOfB; // B is mutable
public List<B> getListOfB(){
return Collections.unmodifiableList(this.listOfB);
}
}
现在他说,即使在获取getListOfB()之后,他也可以更改“B”实例,并希望我也避免这种情况。然后我说。
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不能是不变的。
最佳答案
假设B
是A
的接口或接口的实现,则可以分别使用listOfB
或java.net.Proxy
的B
包裹A
的每个元素,而通过抛出UnsupportedOperationException
来拦截所有修改调用。
更详细地,将listOfB
的每个项目替换为java.net.Proxy
包装的实例,实现A
。然后,每当有人获取listOfB
项时,他都会获取包装的实例。每当有人在这种包装好的物品上呼叫塞特犬时,都要拦截该呼叫并抛出UnsupportedOperationException
。希望你明白我的意思。基本上就是Collections.unmodifiableXXX()
所做的。如果您了解所有可能会修改listOfB
项状态的方法,则B
不必是POJO
。只需确保包装器抛出异常即可替换所有修改方法。