将参数化的类实例传递给构造函数 [英] Passing parameterized Class instance to the constructor
问题描述
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>
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屋!