简体   繁体   English

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

[英]Passing parameterized Class instance to the constructor

I have lost in the Jungle of Generics, please help me :) I have something like this: 我迷失在仿制药的丛林中,请帮助我:)我有这样的事情:

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); 
    }
}

As far as I think, the compiler should accept Argument since it implements RefreshableInterface . 据我所知,编译器应该接受Argument因为它实现了RefreshableInterface

  • Why do I get this error? 为什么我会收到此错误?
  • How can I make the ProblematicClass working? 如何让ProblematicClass工作?

ps: if you have better title for this, please change it. ps:如果你有更好的头衔,请更改它。 I could not make up better. 我无法弥补更好。

Issue is, your constructor expects a Class<T> , and T in your code is inferred as Argument<AnyOtherClassDescendant> . 问题是,您的构造函数需要Class<T> ,并且代码中的T被推断为Argument<AnyOtherClassDescendant>

So, you should pass a Class<Argument<AnyOtherClassDescendant>> , and you're passing Class<Argument> . 所以,你应该传递一个Class<Argument<AnyOtherClassDescendant>> ,然后传递Class<Argument> But you can't pass that Class instance directly, as you cannot do Argument<AnyOtherClassDescendant>.class . 但是你不能直接传递那个Class实例,因为你不能做Argument<AnyOtherClassDescendant>.class

You can however, solve the issue by typecasting the class to required instance: 但是,您可以通过将类类型转换为必需的实例来解决问题:

public ProblematicClass() {
    super((Class<Argument<AnyOtherClassDescendant>>)(Class<?>)Argument.class); 
}

Note, how you've to typecast Class<Argument> first to Class<?> , and then the resultant type to Class<Argument<AnyOtherClassDescendant>> . 注意,如何将Class<Argument>首先类型Class<Argument<AnyOtherClassDescendant>> Class<?> ,然后将结果类型类型Class<Argument<AnyOtherClassDescendant>> There is no simple way to achieve that. 没有简单的方法可以实现这一目标。

The reason behind this is, there is only a single Class instance for all parameterized instantiation of a generic type, that is associated with the class itself. 这背后的原因是,泛型类型的所有参数化实例化只有一个Class实例,它与类本身相关联。 A single compilation unit of a generic type, compiles to just a single class file. 泛型类型的单个编译单元,仅编译为单个类文件。 I guess this is different in how C++ implements templates. 我想这与C ++实现模板的方式不同。 There you get different machine codes for different instantiation. 在那里,您可以获得不同实例化的不同机器代码。

So, if you execute the below code, you'll get true as output: 所以,如果你执行下面的代码,你会得到true的输出:

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

boolean isSameClassInstance = strList.getClass() == intList.getClass();
System.out.println(isSameClassInstance);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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