Java泛型类型变量

6

我的问题涉及泛型类和方法中使用的类型变量。

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

我知道在编译期间泛型信息会被擦除,并且一切都会转换为 Object,那么为什么编译器不假定 T 是一个对象并让我们构造它呢?


这是一个很好的问题。它说明了Java泛型固有的一些缺点和抽象中的一些漏洞。顺便说一下,由于类型擦除,你也无法创建一个数组T[]以解决这个问题。 - Christian Mann
2个回答

9
问题在于,在运行时JVM不知道T实际代表哪个类(这些信息在运行时不保留,这就是所谓的“类型擦除”)。因此,JVM只看到你想要构造一个新的T,但不知道实际上要调用哪个构造函数 - 因此这是不允许的。
虽然有一些解决方法,但它们不能像你提出的那样工作。
引用:

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

当然,运行时可以为您构造java.lang.Object的实例,但这确实没有帮助,因为您真正想要的是一个T

一个问题,运行时看到的是 T 还是 Object?泛型信息不是被擦除了吗,难道不是吗? - Ibrahim Najjar
我不知道运行时“看到”什么,因为我不知道这是如何在内部实现的。我相信它根本没有看到任何类型。它可能可以区分代码中真正写有“Object”的情况和擦除了类型的情况。 - sleske

2

除了sleske的回答之外,如果你需要在泛型类中创建T的对象,则解决方案是传递一个Class<T>引用作为构造函数或需要创建新对象的方法的参数,并使用该类来创建新实例。


是的,这就是我所说的“有变通方法”。谢谢你加上了它 :-). - sleske
我不赞成这种做法,但如果你喜欢编写非常糟糕的代码,仍然可以使用反射绕过它。((ParametrizedType)getClass()).getActualTypeArguments()[0].createNewInstance()。当然,这假定存在默认构造函数。 - Joeri Hendrickx

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