如果我有这样的抽象类:
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()是荒谬的.
要做你想做的事,你需要使用反射.您无法从编译时错误检查中受益.