[英]Java call super class constructor with generic class object
I've a class like this: 我上了这样的课:
public class GenericClass<T> {
public void wrap(T item) {...}
}
public abstract class AbstractClass<T, G extends GenericClass<T>> {
protected G wrapper;
public AbstractClass(Class<G> generic, T something) {
wrapper = generic.newInstance();
wrapper.wrap(something);
}
public G wrapAndGet(T item) throws Exception {
wrapper.wrap(item);
return wrapper;
}
}
// 90% of the time people only need this:
public class GeneralClass<T> extends AbstractClass<T, GenericClass<T>> {
public GeneralClass(T something) {
super(GenericClass.class, something); // !error, asking for Class<GenericClass<T>>
}
}
// and use it like this:
new GeneralClass<String>("foo").wrapAndGet("bar");
// but sometimes you might need:
public class AdvancedWrapper<T> extends GenericClass<T> {
public T advancedMethod();
}
public class ClassUseAdvancedWrapper<T> extends AbstractClass<T, AdvancedWrapper<T>> {
public ClassUseAdvancedWrapper(T something) {
super(AdvancedWrapper.class, something); // error, but let's say it compiles
}
}
// then you can use:
new ClassUseAdvancedWrapper<String>("foo").wrapAndGet("bar").advancedMethod();
This doesn't make sense to me: aren't GenericClass<T>
and GenericClass having the same class at runtime? 这对我来说没有意义:
GenericClass<T>
和GenericClass在运行时是否具有相同的类吗? How can I get the class object of GenericClass<T>
then? 那我怎样才能得到
GenericClass<T>
的类对象呢?
EDIT: add use case 编辑:添加用例
Class literals, ex. 类文字,例如。
Foo.class
, don't include generic type information. Foo.class
,不包括泛型类型信息。 The JLS states JLS州
The type of
C.class
, whereC
is the name of a class, interface, or array type (§4.3), isClass<C>
.C.class
类型为Class<C>
,其中C
是类,接口或数组类型(第C.class
)的名称。
This also means that the type of the expression contains a raw type, ie. 这也意味着表达式的类型包含原始类型,即。 in
Class<GenericClass>
, GenericClass
is not parameterized and is therefore raw. 在
Class<GenericClass>
, GenericClass
没有参数化,因此是原始的。
So, the problem here is your abstract class' constructor expects 所以,这里的问题是您的抽象类的构造函数期望
Class<G> generic
where G
is G
在哪里
G extends GenericClass<T>>
so (close to) 如此靠近)
Class<G extends GenericClass<T>>
but you are providing 但是你提供
Class<GenericClass>
Those are not assignable. 这些是不可分配的。
You ask 你问
How can I get the class object of GenericClass then?
那我怎样才能得到GenericClass的类对象呢?
You can't. 你不能 It doesn't exist.
它不存在。 At runtime, there is no
Class
object for GenericClass<T>
, there's only a Class
object for GenericClass
. 在运行时,不存在
Class
为对象GenericClass<T>
这里只有一个Class
为对象GenericClass
。
You'd have to explain what you are trying to do in more detail, but you could make your code compile with 您必须更详细地说明您要尝试执行的操作,但是可以使用以下命令编译代码
abstract class AbstractClass<T, G extends GenericClass<T>> {
public AbstractClass(Class<? super G> generic, T something) {
}
}
Now your constructor expects a Class<? super G extends GenericClass<T>>
现在,您的构造函数期望
Class<? super G extends GenericClass<T>>
Class<? super G extends GenericClass<T>>
and you are providing a Class<GenericClass>
. Class<? super G extends GenericClass<T>>
并且您正在提供Class<GenericClass>
。 In your super
constructor invocation GenericClass<T>
is bound to G
and GenericClass
is a supertype of GenericClass<anything>
, so Class<GenericClass>
is assignable to a Class<? super GenericClass<T>>
在您的
super
构造函数调用中, GenericClass<T>
绑定到G
而GenericClass
是GenericClass<anything>
的超类型,因此Class<GenericClass>
可分配给Class<? super GenericClass<T>>
Class<? super GenericClass<T>>
. Class<? super GenericClass<T>>
。 You'll find there are many other limitations with this solution. 您会发现此解决方案还有许多其他限制。 It all depends on your goal.
这完全取决于您的目标。
This is what I had to do to get some code to compile. 这是我需要做的一些编译代码。 I don't know what you are trying to do, but at least this gives a blueprint to follow.
我不知道您要做什么,但是至少这给出了一个可遵循的蓝图。 The main problem I saw was that
AbstractClass
needs two arguments for its CTOR, and you can't do that by passing only one argument to the CTOR of GeneralClass
, so I had to add a second argument. 我看到的主要问题是
AbstractClass
的CTOR需要两个参数,而您不能通过仅将一个参数传递给GeneralClass
的CTOR来做到这一点,因此我不得不添加第二个参数。
public class GenericTest {
public static void main(String[] args) {
GenericClass<Integer> generic = null;
AbstractClass<Integer, GenericClass<Integer>> abstr = new AbstractClass( generic.getClass(), 1 );
GeneralClass<Integer, GenericClass<Integer>> general = new GeneralClass( generic.getClass(), 1 );
}
}
class GenericClass<T> {
}
class AbstractClass<T, G extends GenericClass<T>> {
public AbstractClass(Class<G> generic, T something) {
}
}
class GeneralClass<T,G extends GenericClass<T>>
extends AbstractClass<T, G> {
public GeneralClass( Class<G> generic, T something) {
super( generic, something);
}
}
EDIT: So to echo the discussion in the comments, I made AbstractClass
concrete so I could show what arguments its constructor takes. 编辑:因此,为了回应评论中的讨论,我将
AbstractClass
具体化,以便可以显示其构造函数采用的参数。 (Also, I had to do that in my own code to figure out what the heck was going on, so I'm showing my work.) (此外,我必须在自己的代码中执行此操作以弄清楚到底发生了什么,因此,我正在展示自己的工作。)
I hope the examples/test cases in the main method above make it clear what's going on. 我希望上面主要方法中的示例/测试用例可以清楚说明正在发生的事情。 To reiterate what Sotirios Delimanolis said:
重申Sotirios Delimanolis的看法:
How can I get the class object of GenericClass then?
You can't.
你不能 It doesn't exist.
它不存在。 At runtime, there is no Class object for GenericClass, there's only a Class object for GenericClass.
在运行时,GenericClass没有Class对象,GenericClass只有Class对象。
GenericClass in this case sets T = Integer. 在这种情况下,GenericClass设置T =整数。 There's clearly no relationship between the system class Integer and the class you just declared.
系统类Integer与您刚刚声明的类之间显然没有任何关系。 There's no
get()
you can call on an integer to get your class GenericClass
. 没有
get()
可以调用整数来获取类GenericClass
。 I think my example makes this plain as day. 我认为我的榜样使这一天变得平淡无奇。
You could I suppose make some sort of processing tool that scans .java files or .class files, and builds a database of type parameters used by GenericClass (and its subclasses?), but that's boarding on crazy unfeasible. 您可以假设我可以制作一种处理工具,该工具可以扫描.java文件或.class文件,并建立GenericClass(及其子类?)使用的类型参数的数据库,但是这简直是行不通的。 If you have the resources, it could be done, but it won't make sense for any but the largest projects, and probably only a public framework at that.
如果您有足够的资源,则可以完成此工作,但是对于最大的项目,除了最大的项目之外,其他任何项目都没有意义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.