我迷失在仿制药的丛林中,请帮助我:)我有这样的事情:
public class BaseClass<TYPE> {
public BaseClass(Class<TYPE> clazz) {};
}
public class FirstLevelClass<REFRESHABLE
extends RefreshableInterface> extends BaseClass<REFRESHABLE> {
public FirstLevelClass(Class<REFRESHABLE> clazz) {
super(clazz);
};
}
public class Argument<T extends AnyOtherClass>
implements RefreshableInterface {
public refresh() {}
}
pulbic class ProblematicClass
extends FirstLevelClass<Argument<AnyOtherClassDescendant>> {
public ProblematicClass() {
//Compiler error: Constructor
//FirstLevelClass<Argument<AnyOtherClassDescendant>>(Class<Argument>) is undefined
super(Argument.class);
}
}
据我所知,编译器应该接受Argument
,因为它实现了RefreshableInterface
。
ProblematicClass
正常工作?ps:如果你有更好的头衔,请改变它。我无法弥补。
答案 0 :(得分:10)
问题是,您的构造函数需要Class<T>
,并且代码中的T
被推断为Argument<AnyOtherClassDescendant>
。
因此,您应该传递Class<Argument<AnyOtherClassDescendant>>
,然后传递Class<Argument>
。但是您无法直接传递Class
实例,因为您无法Argument<AnyOtherClassDescendant>.class
。
但是,您可以通过将类类型转换为必需的实例来解决问题:
public ProblematicClass() {
super((Class<Argument<AnyOtherClassDescendant>>)(Class<?>)Argument.class);
}
注意,您要先将Class<Argument>
首先Class<?>
转换为Class<Argument<AnyOtherClassDescendant>>
,然后将结果类型转换为Class
。没有简单的方法可以实现这一目标。
这背后的原因是,泛型类型的所有参数化实例化只有一个true
实例,它与类本身相关联。泛型类型的单个编译单元,仅编译为单个类文件。我想这与C ++实现模板的方式不同。在那里,您可以获得不同的机器代码以进行不同的实例化。
因此,如果您执行以下代码,您将获得List<String> strList = new ArrayList<String>();
List<Integer> intList = new ArrayList<Integer>();
boolean isSameClassInstance = strList.getClass() == intList.getClass();
System.out.println(isSameClassInstance);
作为输出:
{{1}}