ImmutableList 不扩展 List?
ImmutableList does not extend List?
当我深入研究 ImmutableList
的 gs-collection 源代码时,它没有扩展 java.util.List
。但是 class javadoc 提到所有 ImmutableList 实现必须实现 java.util.List
.
为什么必须要求实施来实施 java.util.List
而不是 ImmutableList
本身来扩展 java.util.List
?
为什么 ImmutableList
不扩展 List
?
ImmutableCollection
doesn't extend java.util.Collection
(and 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.
"the specified object is also a list?"是什么意思 我们在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
界面。
互操作
此设计的一个好处是 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 的开发者。
当我深入研究 ImmutableList
的 gs-collection 源代码时,它没有扩展 java.util.List
。但是 class javadoc 提到所有 ImmutableList 实现必须实现 java.util.List
.
为什么必须要求实施来实施 java.util.List
而不是 ImmutableList
本身来扩展 java.util.List
?
为什么 ImmutableList
不扩展 List
?
ImmutableCollection
doesn't extend java.util.Collection
(and 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.
"the specified object is also a list?"是什么意思 我们在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
界面。
互操作
此设计的一个好处是 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 的开发者。