当我深入研究 ImmutableList
的 gs-collection 源代码时,它没有扩展 java.util.List
。然而类 javadoc 提到所有 ImmutableList 实现必须实现 java.util.List
。
为什么必须要求实现实现 java.util.List
而不是 ImmutableList
本身来扩展 java.util.List
?
最佳答案
为什么 ImmutableList
不扩展 List
?
ImmutableCollection
不扩展 java.util.Collection
(并且 ImmutableList
不扩展 java.util.List
)因为 Collection
有变异方法像 add()
和 remove()
。如果不可变集合有这些方法,它们将始终抛出 UnsupportedOperationException
。对于不可变集合的用户,将自动完成选项中的 add()
和 remove()
视为可调用方法会很奇怪。
为什么 Javadoc 强加了所有 ImmutableList
实现也实现 List
的契约?
归结为平等。一个 ImmutableList
应该等于一个 List
,假设两个列表具有相同的内容和相同的顺序。 List.equals()
imposes a Javadoc contract其中指出:
Returns true if and only if the specified object is also a list, both lists have the same size, and all corresponding pairs of elements in the two lists are equal.
“指定的对象也是一个列表”是什么意思?我们可以在AbstractList.equals()
中看到,它的意思是instanceof List
。
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
return false;
...
}
因此,所有 ImmutableList
实现还必须实现 List
,以便 equals()
以对称方式工作。不可变集合工厂已经隐藏了实现细节,例如具有单个元素的不可变列表是由 ImmutableSingletonList
实现的。它还最终隐藏了 List
接口(interface)。
互操作
这种设计的一个好处是 ImmutableList
可以转换为 List
,这对于与现有 API 的互操作很重要。
// Library method - cannot refactor the parameter type
public void printAll(List<?> list)
{
for (Object each : list)
{
System.out.println(each);
}
}
ImmutableList<Integer> immutableList = Lists.immutable.with(1, 2, 3);
List<Integer> castList = immutableList.castToList();
printAll(castList);
// also works
printAll((List<?>) immutableList);
// throws UnsupportedOperationException
castList.add(4);
注意:我是 GS Collections 的开发人员.
关于java - ImmutableList 不扩展 List?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29504881/