为什么Java泛型类型参数在运行时不是具体化的?

6

我的理解是,C#和Java在某些方面的泛型方式存在差异,其中一个差异是,在C#/.NET中,泛型类型参数可在运行时使用,而在Java中则不可以。那么,为什么Java语言设计者要这样做呢?

2个回答

9
为了允许新代码与旧代码进行接口,因此允许与预先生成的字节码具有二进制兼容性。来自Java教程的类型擦除页面:

类型擦除使使用泛型的Java应用程序能够与在泛型出现之前创建的Java库和应用程序保持二进制兼容性。

[...]

类型擦除存在是为了使新代码可以继续与旧代码进行接口。

有关相关问题,请查看C# vs Java generics

4
我记得在《Hardcore Java》一书中读到过这方面的内容:
检查集合中的元素可能会非常耗费时间,它的效率顺序仅为O(n)。如果您的集合中只有10个地址,则检查元素很容易。但是,如果集合包含15,000个地址,则每当某人调用setter时,都会产生显着的开销。
另一方面,如果您能够在编译时防止用户放置除地址以外的任何东西到集合中,那么您就不必在运行时检查类型。如果他们试图给您提供不是地址的东西,那么编译器将拒绝该尝试。这正是参数化类型所做的。
然而,“为什么”问题永远无法得到令人满意的答案,因为涉及到的变量太多了,包括人员、时间、地点和政治。我记得在其他地方读到过,这个决定与保持与Java字节代码中已经存在的方式兼容有很大关系。以下是同一本书中的另一句话:
在编译器解析了泛型引入的类型安全性之后,它会从类型中擦除参数化信息。因此,在运行时不可用此信息。擦除的目的,如Sun所述,是允许使用旧版JDK构建的类库能够在JDK 1.5虚拟机上运行。
我很好奇,运行时泛型提供了哪些优势?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接