Collections.unmodifiableList(...)
返回 静态内部类 UnmodifiableList
的新实例。其他不可修改的集合类的构造方式相同。
如果这些类是公开的,其中一个有两个优点:
- 能够指示更具体的返回值(例如
UnmodifiableList
),因此 API 用户不会想到修改该集合; - 能够在运行时检查
List
是否为instanceof UnmodifiableList
。
那么,公开这些类(class)是否有任何不优势?
编辑:没有提出绝对令人信服的论据,所以我选择了最受好评的答案。
最佳答案
我个人完全同意你的看法。问题的核心在于 Java 的泛型不是协变的,这反过来又是因为 Java 的集合是可变的。
Java 的类型系统不可能将一个看似具有mutators 的类型实际上是不可变的。想象一下,如果我们要开始设计一些解决方案:
interface Immutable //marker for immutability
interface ImmutableMap<K, V> extends Map<K, V>, Immutable
但是 ImmutableMap
是 Map
的子类,因此 Map
可以从 ImmutableMap
分配,所以任何方法它返回这样一个不可变的 Map:
public ImmutableMap<K, V> foo();
可以分配给 Map,因此可以在编译时进行变异:
Map<K, V> m = foo();
m.put(k, v); //oh dear
因此,您可以看到添加这种类型实际上并没有阻止我们做任何坏事。我认为出于这个原因做出了一个判断,它没有提供足够的东西。
像 scala 这样的语言具有声明站点差异注释。也就是说,您可以将类型指定为协变(因此是不可变的),因为 Scala 的 Map 是(实际上它在其 V
参数中是协变的)。因此,您的 API 可以声明其返回类型是可变的还是不可变的。
另外,Scala 允许您声明交集类型,因此您甚至不需要将 ImmutableXYZ
接口(interface)创建为单独的实体,您可以指定一个返回方法:
def foo : XYZ with Immutable
但是 scala 有一个正确的类型系统,而 Java 没有
关于Java 集合 API : why are Unmodifiable[List|Set|Map] not publicly visible classes?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4296619/