2010-10-26 75 views
6

我的问题是关于泛型类和方法中使用的类型变量。Java通用类型变量

为什么我们不能这样做T = new T();或换句话说,为什么我们不能构造一个类型变量的对象?

我知道,在编译过程中的通用信息将被删除,一切都转化为
对象,那么为什么不编译器假定T是一个对象,让我们构建呢?

+0

这是一个很好的问题。它说明了Java泛型中固有的一些缺陷以及抽象中的一些泄漏。顺便说一句,你也不能创建一个数组'T []'出于同样的原因 - 类型擦除。 – 2010-10-26 08:38:07

回答

9

问题是,在运行时,JVM不知道T实际上代表了哪个类(该信息在运行时不保留,这就是“类型擦除”的含义)。因此,JVM只是看到你想构建一个新的T,但不知道实际调用哪个构造函数 - 因此它是不允许的。

有解决方法,但它不会按您的建议工作。

为什么不编译器,假定T 是一个对象,让我们构造它 ?

嗯,当然,运行时可能只是构建的java.lang.Object给你一个实例,但不会真正的帮助,因为你真的想要一个T

+0

有一点,运行时看到T或Object,是不是通用信息擦除了? – 2010-10-26 08:37:20

+0

我不知道运行时“看到”什么,因为我不知道这是如何在内部实现的。我相信它根本没有看到任何类型。它可能可以区分代码中真正存在“Object”的情况以及类型被擦除的情况。 – sleske 2010-10-26 08:41:24

+1

它只是看到一个“对象”。 – 2010-10-26 09:03:39

2

除了sleske的回答,如果您需要在泛型类中创建T的对象,解决方案是将参考作为参数传递给构造函数或需要创建新对象并使用该类创建新实例的方法。

+1

或通过工厂? – Ishtar 2010-10-26 08:40:51

+0

是的,这就是我所说的“有解决方法”。感谢您添加它:-)。 – sleske 2010-10-26 08:42:34

+0

我不会宽恕这种方法,但是如果你喜欢编写非常黑的代码,你仍然可以使用反射来解决它。 '((ParametrizedType)的getClass())。getActualTypeArguments()[0] .createNewInstance()'。这当然假设一个默认的构造函数。 – 2010-10-26 10:02:55