Cedric 最近 提出了类型擦除的话题,结论是
总的来说,我对擦除很满意,希望 Java 的未来版本能优先考虑更急需的功能
好吧,我想擦除并不是我最讨厌的 Java 东西,但它确实位列其中。Java 的部分具体化类型系统实际上给类型系统增加了意想不到的复杂性和不直观的行为。
从纯语言设计的角度来看,我认为部分具体化类型系统可能是你可能做出的最糟糕的决定。要么像 C# 一样对所有类型进行具体化,要么像 ML 一样不对任何类型进行具体化。看,有些语言特性根本不能与类型擦除很好地配合。一个例子:重载。你可以有类型擦除,或者 你可以有重载(或者,像 Ceylon 一样,两者都不可以)。你不能同时有类型擦除 和 重载。不,Java 不是 这一点的反例!在语言设计方面,Java 的具体化方法几乎无法证明是合理的,除非作为一个完全半成品和错误的解决方案,因为根本没有时间做到正确。
Cedric 是从一个纯粹的实际观点出发的,说这些问题在真正的工作中并没有给他带来太多麻烦。好吧,我可以理解这一点。所以,这里是我认为具体化泛型 确实 需要,并且如果在不进一步破坏 Java 的类型系统的情况下能够添加到 Java 中的原因。
框架
许多框架依赖于具体化类型。类型参数擦除削弱了与泛型类型一起工作的框架,并导致了一些糟糕的解决方案,比如 CDI 中的这个解决方案。
类型安全缩小
而不是 Java 风格的instanceof运算符,以及C样式的类型转换,Ceylon提供了一种在完全静态类型安全的方式下缩小引用类型的构造方法。您根本无法在Ceylon中得到ClassCastException异常。
但是,这个功能依赖于泛型的实例化。在我们实现泛型参数实例化之前,我们无法提供任何将类型缩小到参数化类型的机制。现在,您无法将Object类型缩小为List
。您可能认为这是Ceylon的问题,但实际上,Java的情况也好不到哪里去。Java的instanceof运算符不支持带有类型参数的类型,并且将类型转换为带有类型参数的类型是一种完全不安全的操作!我认为在静态类型语言中,这种行为是不可接受的。
跨语言互操作性
当一些语言支持泛型实例化而另一些不支持时,静态类型JVM语言之间的互操作性将会变得非常混乱。特别是,很容易想象那些支持泛型实例化的语言不会以互操作的方式支持它们。这可能会成为多语言JVM愿景的一个真正问题。