sal*_*sal 68 java generics collections jvm reification
我已经阅读过Neal Gafter关于这个主题的博客,但我仍然不清楚其中的一些观点.
为什么在给定Java的当前状态,JVM和现有集合API的情况下,不可能创建保留类型信息的Collections API的实现?难道这些不能以保留向后兼容性的方式替换未来Java版本中的现有实现吗?
举个例子:
List<T> list = REIList<T>(T.Class);
Run Code Online (Sandbox Code Playgroud)
REIList是这样的:
public REIList<T>() implements List {
private Object o;
private Class klass;
public REIList(Object o) {
this.o = o;
klass = o.getClass();
}
... the rest of the list implementation ...
Run Code Online (Sandbox Code Playgroud)
并且这些方法使用Object o和Class klass来获取类型信息.
为什么保留泛型类信息需要语言更改而不仅仅是JVM实现更改?
我不明白的是什么?
ghe*_*ton 36
重点是,在编译器中,reified泛型支持保留类型信息,而类型擦除泛型则不支持.AFAIK,首先进行类型擦除的重点是启用向后兼容性(例如,较低版本的JVM仍然可以理解泛型类).
您可以如上所述在实现中显式添加类型信息,但每次使用列表时都需要额外的代码,而且在我看来非常混乱.此外,在这种情况下,您仍然没有对所有列表方法进行运行时类型检查,除非您自己添加检查,但是确定的泛型将确保运行时类型.
Ric*_*mes 18
与大多数Java开发人员的信念相反,尽管采用非常有限的方式,仍可以保留编译时类型信息并在运行时检索此信息.换句话说:Java确实以非常有限的方式提供了具体化的泛型.
请注意,在编译时,编译器具有可用完整的类型的信息,但该信息被故意中断的一般当产生的二进制代码,在被称为一个处理类型擦除.由于兼容性问题,这是以这种方式完成的:语言设计者的意图是提供完整的源代码兼容性和平台版本之间的完全二进制代码兼容性.如果以不同方式实现,则在迁移到较新版本的平台时,必须重新编译旧版应用程序.完成它的方式,保留所有方法签名(源代码兼容性),您不需要重新编译任何东西(二进制兼容性).
如果需要保留编译时类型信息,则需要使用匿名类.关键是:在匿名类的非常特殊的情况下,可以在运行时检索完整的编译时类型信息,换言之,意思是:具体化的泛型.
我写了一篇关于这个主题的文章:
http://rgomes-info.blogspot.co.uk/2013/12/using-typetokens-to-retrieve-generic.html
在文章中,我描述了用户对该技术的反应.概括地说,这是一个不起眼的主体和技术(或者图案,如果你喜欢)看起来无关的大多数Java开发.
我上面提到的文章链接到源代码,它实现了这个想法.
Har*_*lby 12
IIRC(并且基于链接),Java泛型只是现有使用Object集合和来回转换技术的语法糖.使用Java泛型更安全,更简单,因为编译器可以为您进行检查,以验证您是否保持编译时类型的安全性.然而,运行时间是一个完全不同的问题.
另一方面,.NET泛型实际上创建了新类型 - List<String>在C#中的类型与a不同List<Int>.在Java中,在幕后,它们是相同的 - a List<Object>.这意味着如果你有一个,你不能在运行时查看它们,看看它们被声明为什么 - 只有它们现在是什么.
改进后的泛型将改变这一点,为Java开发人员提供与.NET现在相同的功能.
| 归档时间: |
|
| 查看次数: |
29070 次 |
| 最近记录: |