问题
我偶尔听说过,通用泛型,Java并没有把它弄好。 (最近的参考,here)
原谅我的经验不足,但是什么会让他们变得更好?
#1 热门回答(129 赞)
坏:
- 类型信息在编译时丢失,因此在执行时你无法确定它的"含义"类型
- 不能用于值类型(这是一个大问题 - 在.NET中,List <byte>确实由byte []支持,例如,不需要装箱)
- 调用泛型方法的语法很糟糕(IMO)
- 约束的语法可能会令人困惑
- 通配符通常令人困惑
- 由于上述铸造等各种限制
好:
- 通配符允许在呼叫方指定协方差/逆变,这在许多情况下非常简洁
- 总比没有好!
#2 热门回答(25 赞)
最大的问题是Java泛型只是一个编译时的东西,你可以在运行时颠覆它。 C#受到称赞,因为它进行了更多的运行时检查。在this post中有一些非常好的讨论,它与其他讨论有关。
#3 热门回答(13 赞)
- 运行时实现(即不是类型擦除);
- 使用原始类型的能力(这与(1)有关);
- 虽然通配符很有用,但语法和知道何时使用它会让很多人感到困惑。和
- 没有性能提升(因为(1); Java泛型是铸造对象的语法糖)。
(1)导致一些非常奇怪的行为。我能想到的最好的例子是。承担:
public class MyClass<T> {
T getStuff() { ... }
List<String> getOtherStuff() { ... }
}
然后声明两个变量:
MyClass<T> m1 = ...
MyClass m2 = ...
现在致电getOtherStuff()
:
List<String> list1 = m1.getOtherStuff();
List<String> list2 = m2.getOtherStuff();
第二个是它的泛型类型参数被编译器剥离,因为它是一个原始类型(意味着没有提供参数化类型),即使它与参数化类型没有关系。
我还会提到我最喜欢的JDK声明:
public class Enum<T extends Enum<T>>
除了通配符(这是一个混合包)我只是认为.Net泛型更好。