ImmutableList不扩展List?
当我深入研究ImmutableList
的gs-collection源代码时,它不会扩展java.util.List
。 但是,类javadoc提到All 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()
强加一个Javadoc契约 ,该契约声明:
当且仅当指定的对象也是列表时,返回true,两个列表具有相同的大小,并且两个列表中的所有对应元素对都相等。
“指定的对象也是一个列表是什么意思?” 我们可以在AbstractList.equals()
看到它表示instanceof List
。
public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof List)) return false; ... }
因此,所有ImmutableList
实现也必须实现List
for equals()
以对称方式工作。 不可变集合工厂已经隐藏了实现细节,例如具有单个元素的不可变列表由ImmutableSingletonList
实现。 它还最终隐藏了List
接口。
互操作
这种设计的一个好处是可以将ImmutableList
为List
,这对于与现有API互操作很重要。
// Library method - cannot refactor the parameter type public void printAll(List> list) { for (Object each : list) { System.out.println(each); } } ImmutableList immutableList = Lists.immutable.with(1, 2, 3); List castList = immutableList.castToList(); printAll(castList); // also works printAll((List>) immutableList); // throws UnsupportedOperationException castList.add(4);
注意:我是GS Collections的开发人员。