就我个人而言,我完全同意你的看法。问题的核心是Java的泛型不是协变的,这反过来又是因为Java的集合是可变的。
Java的类型系统不可能编纂一个似乎有突变体的类型实际上是不可变的。想象一下,如果我们开始设计一些解决方案:
interface Immutable //marker for immutability
interface ImmutableMap<K, V> extends Map<K, V>, Immutable
但是 then 是 的子类,因此可以从 so 任何返回这样一个不可变 Map 的方法进行赋值:ImmutableMap
Map
Map
ImmutableMap
public ImmutableMap<K, V> foo();
可以分配给 Map,因此可以在编译时进行更改:
Map<K, V> m = foo();
m.put(k, v); //oh dear
因此,您可以看到,添加此类型实际上并没有阻止我们做任何坏事。我认为,出于这个原因,有人作出判断,认为它没有足够的能力提供。
像 scala 这样的语言具有声明站点方差注释。也就是说,您可以将类型指定为协变(因此不可变),就像Scala的Map一样(实际上它的参数是协变的)。因此,您的 API 可以声明其返回类型是可变的还是不可变的。V
另一方面,Scala允许您声明交集类型,这样您甚至不需要将接口创建为单独的实体,您可以指定一个要返回的方法:ImmutableXYZ
def foo : XYZ with Immutable
但是Scala有一个合适的类型系统,而Java没有。