我是这样的一个班级:
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();
这对我来说没有意义:aren&#39; t GenericClass<T>
和GenericClass在运行时具有相同的类?我怎样才能获得GenericClass<T>
的类对象呢?
编辑:添加用例
答案 0 :(得分:5)
班级文字,例如Foo.class
,不包含泛型类型信息。 The JLS states
C.class
的类型,C
是类,接口或数组类型(第4.3节)的名称,是Class<C>
。
这也意味着表达式的类型包含原始类型,即。在Class<GenericClass>
中,GenericClass
未参数化,因此是原始的。
所以,这里的问题是你的抽象类'构造函数期望
Class<G> generic
其中G
是
G extends GenericClass<T>>
所以(接近)
Class<G extends GenericClass<T>>
但是你提供
Class<GenericClass>
那些不可转让。
你问
如何获取GenericClass的类对象呢?
你做不到。它不存在。在运行时,Class
没有GenericClass<T>
个对象,Class
只有GenericClass
个对象。
你必须更详细地解释你想要做的事情,但你可以用
编译你的代码abstract class AbstractClass<T, G extends GenericClass<T>> {
public AbstractClass(Class<? super G> generic, T something) {
}
}
现在,您的构造函数需要Class<? super G extends GenericClass<T>>
,并且您提供Class<GenericClass>
。在您的super
构造函数调用中,GenericClass<T>
绑定到G
,而GenericClass
是GenericClass<anything>
的超类型,因此Class<GenericClass>
可分配给Class<? super GenericClass<T>>
1}}。您会发现此解决方案还有许多其他限制。这一切都取决于你的目标。
答案 1 :(得分:2)
这是我需要做的一些代码来编译。我不知道你要做什么,但至少这给了一个蓝图。我看到的主要问题是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);
}
}
编辑:所以为了回应评论中的讨论,我使AbstractClass
具体化,以便我可以展示其构造函数所采用的参数。 (另外,我必须在我自己的代码中做到这一点,以弄清楚到底发生了什么,所以我正在展示我的工作。)
我希望上面主要方法中的示例/测试用例清楚地说明发生了什么。重申Sotirios Delimanolis所说的话:
在这种情况下,How can I get the class object of GenericClass then?
你做不到。它不存在。在运行时,没有Class对象 GenericClass,GenericClass只有一个Class对象。
GenericClass设置T = Integer。系统类Integer与您刚刚声明的类之间显然没有任何关系。没有get()
你可以调用一个整数来获得你的班级GenericClass
。我认为我的例子就是这一天。
我可以假设制作一些扫描.java文件或.class文件的处理工具,并构建一个GenericClass(及其子类?)使用的类型参数数据库,但是这种方法在疯狂上是不可行的。如果你有资源,那么它可以完成,但除了最大的项目之外没有任何意义,可能只有一个公共框架。