作者:huanhuan199538 | 来源:互联网 | 2023-10-16 09:27
我需要实现不可变列表接口并修改其方法以确保列表的不可变性。
我认为我已经做到了,但是无法确保在此列表中找到的可变对象具有这种不变性。
考虑以下界面:
public interface ImmutableListInterface{
T get(int index);
}
及其实现:
public final class ImmutableList implements ImmutableListInterface{
private final List immutableList;
public ImmutableList(List list) {
immutableList = list;
}
@Override
public T get(int index) {
T item;
List 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 list = new LinkedList();
MutableObject object = new MutableObject();
object.a = 0;
list.add(object);
ImmutableList immutable_list = new ImmutableList(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
我尝试将方法设置为final,但无济于事。
似乎我可能忽略了我的实现中的某些内容。我如何真正确保列表的不变性,让对象本身保持可变性?
出现问题的原因是get()
方法返回的对象是引用与您实际列表中的同一对象。因此,对其所做的更改将应用于您实际列表的对象。
另一方面,您不能确保列表内容的不变性,只能确保未修改其引用,而其值可能会更改。
如果您确实要在列表中保留对象并避免在get()
之后修改列表的内容,建议您在方法中返回对象的深层副本。它将返回带有全新参考的相同对象,该参考不会链接到您的列表。
有几种方法可以找到,in this question