嗨,我被问到这个采访问题,您有一个不变类中的对象列表,该类真的是不可变的,可以修改什么以及如何防止它。我给出了以下解决方案。

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不能是不变的。

最佳答案

假设BA的接口或接口的实现,则可以分别使用listOfBjava.net.ProxyB包裹A的每个元素,而通过抛出UnsupportedOperationException来拦截所有修改调用。

更详细地,将listOfB的每个项目替换为java.net.Proxy包装的实例,实现A。然后,每当有人获取listOfB项时,他都会获取包装的实例。每当有人在这种包装好的物品上呼叫塞特犬时,都要拦截该呼叫并抛出UnsupportedOperationException。希望你明白我的意思。基本上就是Collections.unmodifiableXXX()所做的。如果您了解所有可能会修改listOfB项状态的方法,则B不必是POJO。只需确保包装器抛出异常即可替换所有修改方法。

08-04 00:05