将参数化的类实例传递给构造函数 [英] Passing parameterized Class instance to the constructor

查看:111
本文介绍了将参数化的类实例传递给构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  public class BaseClass< ; TYPE> {
public BaseClass(Class< TYPE> clazz){};
}

public class FirstLevelClass< REFRESHABLE
extends RefreshableInterface>扩展BaseClass< REFRESHABLE> {

public FirstLevelClass(Class< REFRESHABLE> clazz){
super(clazz);
};
}

公共类参数< T扩展AnyOtherClass>
implements RefreshableInterface {

public refresh(){}
}

pulbic class ProblematicClass
extends FirstLevelClass< Argument< AnyOtherClassDescendant>> {

public ProblematicClass(){
//编译器错误:构造函数
// FirstLevelClass< Argument< AnyOtherClassDescendant>>(Class< Argument>)未定义
超级(Argument.class);


$ / code>

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


  • 为什么我得到这个错误?

  • 如何让 ProblematicClass 工作?



ps:如果您对此有更好的标题,请更改它。问题是,你的构造函数需要一个 Class< T>

解决方案 / code>和 T 在您的代码中被推断为参数< AnyOtherClassDescendant>



因此,您应该传递 Class< Argument< AnyOtherClassDescendant>>< / code>,并传递类<参数> 。但是你不能直接传递 Class 实例,因为你不能执行参数< AnyOtherClassDescendant> .class 。然而,您可以通过将类强制转换为所需实例来解决问题:

 <$ c $ (<参数< AnyOtherClassDescendant>>)(Class<>)Argument.class); 
}

请注意,如何对类型 Class<参数> 首先到 Class <?> ,然后得到的类型为 Class< Argument< AnyOtherClassDescendant>> 。有没有简单的方法来实现这一点。



这背后的原因是,只有一个 Class 实例用于泛型类型的所有参数化实例化,这与类本身相关联。一个通用类型的单个编译单元只编译为一个类文件。我想这在C ++如何实现模板方面有所不同。你可以得到不同的机器码,用于不同的实例。



所以,如果你执行下面的代码,你会得到 true 作为输出:

 列表< String> strList = new ArrayList< String>(); 
列表<整数> intList = new ArrayList< Integer>();

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


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.

  • Why do I get this error?
  • How can I make the ProblematicClass working?

ps: if you have better title for this, please change it. I could not make up better.

解决方案

Issue is, your constructor expects a Class<T>, and T in your code is inferred as Argument<AnyOtherClassDescendant>.

So, you should pass a Class<Argument<AnyOtherClassDescendant>>, and you're passing Class<Argument>. But you can't pass that Class instance directly, as you cannot do 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>>. 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. 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. There you get different machine codes for different instantiation.

So, if you execute the below code, you'll get true as output:

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

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

这篇关于将参数化的类实例传递给构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆