为什么Javagenerics支持原始types?

为什么Java中的generics使用对象而不是原始types?

例如

Gen<Integer> inum = new Gen<Integer>(100); // works fine, but Gen<int> inums = new Gen<int>(100); // is not allowed. 

Java中的generics是一个完全编译时的结构 – 编译器将所有generics用法转换为正确的types。 这是为了保持与以前的JVM运行时的向后兼容性。

这个:

 List<ClassA> list = new ArrayList<ClassA>(); list.add(new ClassA()); ClassA a = list.get(0); 

变成(大致):

 List list = new ArrayList(); list.add(new ClassA()); ClassA a = (ClassA)list.get(0); 

因此,任何用作generics的东西都必须转换成Object(在这个例子中, get(0)返回一个Object ),而原始types则不是。 所以他们不能用于仿制药。

C#是一个单独的问题 – generics直接作为运行时的一部分实现,因此可以使用基本types – CLR为使用的基元和结构生成新的generics类版本。 唯一的缺点是(直到.NET 4)不允许通用的协变或逆变,不像Java(请参阅generics定义中的superextends关键字)

在Java中,generics的工作方式至less部分是…因为在语言devise之后的几年里,generics被添加到语言中。 语言devise者们被迫select了generics,因为他们不得不提出一个与现有语言和Java类库向后兼容的devise。

其他编程语言(如C ++,C#,Ada)允许使用原始types作为generics的参数types。 但是这样做的另一面是,这种语言的generics(或模板types)实现通常需要为每种types参数化生成genericstypes的独特副本。


1 – generics不包含在Java 1.0中的原因是因为时间压力。 他们觉得必须快速发布Java语言才能填补网页浏览器带来的新的市场机遇。 詹姆斯·高斯林(James Gosling)表示,如果他们有时间的话,他会希望纳入仿制药。 如果发生这种情况,Java语言会是什么样子,这是人们猜测的。

集合被定义为需要一个从java.lang.Object派生的types。 基地根本就不这样做。