调用泛型类型的构造函数

Ram*_*uri 15 java generics

如果我有这样的抽象类:

public abstract class Item
{
    private Integer value;
    public Item()
    {
        value=new Integer(0);
    }
    public Item(Integer value)
    {
        this.value=new Integer();
    }
}
Run Code Online (Sandbox Code Playgroud)

有些类派生自Item,如下所示:

public class Pencil extends Item
{
    public Pencil()
    {
        super();
    }
    public Pencil(Integer value)
    {
        super(value);
    }
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么我不能使用泛型调用构造函数:

public class Box <T extends Item>
{
    T item;
    public Box()
    {
        item=new T(); // here I get the error
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道有可能有一个没有构造函数的类型,但这种情况是不可能的,因为Pencil有没有参数的构造函数,而Item是抽象的.但我从eclipse得到这个错误: 不能实现类型T
我不明白为什么,以及如何避免这种情况?

icy*_*com 13

这是因为Java使用擦除来实现泛型,请参阅:

引用上述维基百科文章中的相关部分:

在编译时检查泛型的类型正确性.然后在称为类型擦除的过程中移除泛型类型信息.

由于类型擦除,无法在运行时确定类型参数.

因此,实例化参数化类型的Java类是不可能的,因为实例化需要调用构造函数,如果类型未知则该构造函数不可用.

您可以通过自己实际提供课程来解决这个问题.这里有很好的解释:


gaw*_*awi 11

无法使用Java类型系统来强制类层次结构具有其子类构造函数的统一签名.

考虑:

public class ColorPencil extends Pencil
{
    private Color color;

    public ColorPencil(Color color)
    {
        super();
        this.color=color;
    }   
}
Run Code Online (Sandbox Code Playgroud)

这使得ColorPencil成为有效的T(它扩展了Item).但是,此类型没有no-arg构造函数.因此,T()是荒谬的.

要做你想做的事,你需要使用反射.您无法从编译时错误检查中受益.