[英]Ensuring immutability for mutable objects in immutable list
我需要实现一个不可变列表接口并修改其方法以确保列表的不变性。
我想我已经设法做到了,但是无法确保在此列表中找到的可变对象的这种不变性。
考虑以下接口:
public interface ImmutableListInterface<T>{
T get(int index);
}
及其实施:
public final class ImmutableList<T> implements ImmutableListInterface<T>{
private final List<T> immutableList;
public ImmutableList(List<T> list) {
immutableList = list;
}
@Override
public T get(int index) {
T item;
List<T> temp = new ArrayList<>(immutableList);
try {
//Try retrieving item
item = temp.get(index);
}catch(Exception e) {
System.out.println("Error message: " + e.getMessage());
return null;
}
return item;
}
}
现在,如果我要初始化 MutableObject 类型的 ImmutableList,这并不妨碍我修改 MutableObject 的属性。 如:
class MutableObject{
public int a;
}
LinkedList<MutableObject> list = new LinkedList<MutableObject>();
MutableObject object = new MutableObject();
object.a = 0;
list.add(object);
ImmutableList<MutableObject> immutable_list = new ImmutableList<MutableObject>(list);
System.out.println("Before:" + immutable_list.get(0).a); //prints 0, as expected
immutable_list.get(0).a = 1;
System.out.println("After:" + immutable_list.get(0).a);//prints 1 - expecting 0
我尝试将方法设置为最终,但无济于事。
似乎我可能忽略了我的实现中的某些内容。 我怎样才能真正确保列表的不变性,让对象本身保持可变?
问题的原因是get()
方法返回的对象引用了实际列表中的同一个对象。 因此,对其所做的更改将应用于实际列表的对象。
另一方面,你不能保证列表内容的不变性,你只能保证它们的引用不被修改,而它们的值可能会改变。
如果您真的想保留列表中的对象并避免在get()
之后修改列表的内容,我建议在您的方法中返回一个对象的深层副本。 它将返回具有全新引用的相同对象,该对象不会链接到您的列表。
有几种方法可以做到这一点,您可以在此问题中找到更多信息
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.