我一直在努力使用Java泛型,这就是我想要做的事情:
...
sortedActions = new ArrayList<BaseAction>();
ActionGroup<? extends BaseAction> actionGroup = null;
for (final BaseAction action : sortedActions) {
Class<? extends BaseAction> clazz = action.getClass();
if (actionGroup == null) {
actionGroup = new ActionGroup<clazz>(); // <-- "clazz cannot be resolved to a type"
}
}
ActionGroup的定义如下: 公共类ActionGroup {...
我不明白这个错误,当我在调试器中检查时,clazz被初始化,它的类型是“java.lang.Class”,它的值是“my.packacge.SubAction”,它是BaseAction的子类,那怎么没有解决一个类型?或者,我在这里不理解什么?
答案 0 :(得分:3)
你不能这样做:角括号之间的部分需要是编译器已知的类型名称,而不是Class<C>
对象,只有在运行时才能为程序所知。
这是不允许的,因为Java中的泛型几乎完全是编译时概念 * 。通用类型参数提供给编译器,以便它可以执行其他类型检查。如果不需要编译时检查,您可以使用该类的非泛型版本,而无需任何额外的成本或收益。
<小时/> * 编译器在编译的代码中留下了泛型的痕迹,例如:在类元数据中,但这几乎是它的范围。
答案 1 :(得分:0)
您正在尝试创建ActionGroup< T >
,其中T
在编译时未知。 @ rgettman的评论提示您new ActionGroup
的语法不正确,因为您试图在clazz
内放置名为<>
的变量而不是类的名称;但是直到运行时才知道哪个类。
最好添加一个工厂方法,为您的M1ssAction类创建ActionGroups并调用该方法。
答案 2 :(得分:0)
这里要理解的是,在Java中,泛型特化是编译时构造,而不是运行时构造。在编译过程中,专业化被“擦除” - 这称为“类型擦除” - 并且生成的字节代码不知道专业化是什么。您无法在运行时确定类 - 这是getClass()函数的作用 - 并在编译时使用它。
“extends”关键字对于定义泛型通常比实例化它们更有用。在这种情况下,您可能需要的是actionGroup为ActionGroup,并为其分配新的ActionGroup<BaseAction>()
- 或者在Java 7中,只是新的ActionGroup&lt;&gt;() - 因为您要实例化实例而不是定义实例通用的。您仍然可以在其中粘贴作为BaseAction子类的对象,因为它们仍然是“BaseAction”的实例。然后,您可以删除action.getClass()调用。