为什么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定义中的super
和extends
关键字)
在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。 基地根本就不这样做。