将参数化的Class实例传递给构造函数

Gáb*_*ták 12 java generics

我迷失在仿制药的丛林中,请帮助我:)我有这样的事情:

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); 
    }
}
Run Code Online (Sandbox Code Playgroud)

据我所知,编译器应该接受,Argument因为它实现RefreshableInterface.

  • 为什么我会收到此错误?
  • 我怎样才能ProblematicClass工作?

ps:如果你有更好的头衔,请更改它.我无法弥补更好.

Roh*_*ain 10

问题是,您的构造函数需要a Class<T>,并T在您的代码中推断为Argument<AnyOtherClassDescendant>.

所以,你应该通过Class<Argument<AnyOtherClassDescendant>>,然后你就过去了Class<Argument>.但是你不能Class直接传递那个实例,就像你做不到的那样Argument<AnyOtherClassDescendant>.class.

但是,您可以通过将类类型转换为必需的实例来解决问题:

public ProblematicClass() {
    super((Class<Argument<AnyOtherClassDescendant>>)(Class<?>)Argument.class); 
}
Run Code Online (Sandbox Code Playgroud)

请注意,你怎么样了,以强制转换Class<Argument>Class<?>,然后将得到的类型Class<Argument<AnyOtherClassDescendant>>.没有简单的方法可以实现这一目标.

这背后的原因是,Class泛型类型的所有参数化实例化只有一个实例,它与类本身相关联.泛型类型的单个编译单元,仅编译为单个类文件.我想这与C++实现模板的方式不同.在那里,您可以获得不同实例化的不同机器代码.

因此,如果您执行以下代码,您将获得true输出:

List<String> strList = new ArrayList<String>();
List<Integer> intList = new ArrayList<Integer>();

boolean isSameClassInstance = strList.getClass() == intList.getClass();
System.out.println(isSameClassInstance);
Run Code Online (Sandbox Code Playgroud)