繁体   English   中英

Java泛型-使用类型为Class的变量 <? extends Whatever> (clazz无法解析为一种类型)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM