[英]Java generics - using a variable of type Class<? extends Whatever> (clazz cannot be resolved to a type)
我一直在与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的定义如下:public class ActionGroup {...
我不明白这个错误,当我在调试器中签入时,clazz被初始化,其类型为“ java.lang.Class”,其值为“ my.packacge.SubAction”,它是BaseAction的子类,因此如何它不解析为一种类型吗? 或者,我在这里不明白什么?
您不能这样做:尖括号之间的部分必须是编译器已知的类型名称,而不是Class<C>
对象,而Class<C>
对象仅在运行时才为您的程序所知道。
这是不允许的,因为Java中的泛型几乎纯粹是一个编译时概念* 。 泛型类型参数提供给编译器,以便它可以执行其他类型检查。 如果不需要编译时检查,则可以使用该类的非泛型版本,而不会产生任何其他成本或收益。
您试图创建一个ActionGroup< T >
,其中在编译时不知道T
@rgettman的注释暗示您的语法对于new ActionGroup
不正确,因为您正试图将名为clazz
的变量而不是<>
内的类名放入; 但是直到运行时您才知道哪个类。
最好将一个创建ActionGroup的工厂方法添加到M1ssAction类中,然后调用该方法。
这里要了解的是,在Java中,泛型专业化是编译时结构,而不是运行时结构。 在编译过程中,专业化被“擦除”-这被称为“类型擦除”-并且生成的字节码不知道什么是专业化。 您无法在运行时确定类-这是getClass()函数的作用-并在编译时使用它。
通常,“ extends”关键字对于定义泛型比对它们进行实例化更有用。 在这种情况下,您可能想要的是将ActionGroup设为ActionGroup,并为其分配新的ActionGroup<BaseAction>()
-或在Java 7中,仅向其分配新的ActionGroup <>()-因为您要实例化实例而不是定义实例。通用。 您仍可以在其中粘贴BaseAction子类的对象,因为它们仍然是BaseAction实例。 然后,您可以删除action.getClass()调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.