带有泛型类对象的Java调用超类构造函数
我上过这样的课:带有泛型类对象的Java调用超类构造函数,java,Java,我上过这样的课: 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
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();
这对我来说毫无意义:GenericClass和GenericClass在运行时不是有相同的类吗?那么我如何获得GenericClass的类对象呢
编辑:添加用例这是我必须做的事情,以获得一些要编译的代码。我不知道你想做什么,但至少这给了你一个蓝图。我看到的主要问题是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);
}
}
你不能。它不存在。在运行时,没有用于的类对象
GenericClass,GenericClass只有一个Class对象
在本例中,GenericClass设置T=Integer。显然,系统类Integer和您刚才声明的类之间没有关系。没有get,您可以调用整数来获取类GenericClass。我想我的例子说明了这一点
我想你可以制作某种处理工具来扫描.java文件或.class文件,并构建一个由GenericClass及其子类使用的类型参数组成的数据库,但这是不可行的。如果你有足够的资源,这是可以做到的,但除了最大的项目,这对任何项目都没有意义,而且可能只是一个公共框架。类文本,例如Foo.Class,不包括泛型类型信息
C.class的类型是class,其中C是类、接口或数组类型§4.3的名称
这也意味着表达式的类型包含原始类型,即inClass,GenericClass未参数化,因此是原始类型
因此,这里的问题是抽象类的构造函数所期望的
Class<G> generic
如此接近
Class<G extends GenericClass<T>>
现在你的构造函数需要一个类,而这段代码不能编译。@DonRoby你是说缺少类吗?我把这些都加进去了。现在的问题是为什么会发生这种通用编译错误。@Sotirios Delimanolis谢谢。正如Sotirios Delimanolis指出的:这是不可能的。如果你特别描述了你想要实现什么,你需要这个类对象做什么,你可能会提出一个替代的解决方案。@Marco13用例addedI我不确定这在语义上是否等同于OP所要求的——特别是,使AbstractClass不再抽象,并向GeneralClass添加第二个类型参数。使AbstractClass具体化让我在main方法中演示它的构造函数是如何工作的。这对普通班的问题来说有点无关紧要。我把它保持原样是因为它让我在main method.Fair中展示了我的测试用例。不过,我不认为更改GeneralClass的类型参数无关紧要。是的,但这是让代码编译的唯一方法。OP能用吗?我不知道。公平地说,它是不同的。答案很长,但并没有朝着正确的方向解决问题:我的代码的目的是在声明GeneralClass时只需要指定T,但是你的代码本质上使AbstractClass和GeneralClass是一样的,那么我为什么要费心去创建它呢?实际上GeneralClass扩展了AbstractClass,在这种情况下,G就是GenericClass。所以本质上编译器拒绝将类分配给类。但是在运行时,这些类应该是同一个类,那么为什么不允许强制转换呢@NSF将运行时放在一边,这是编译时的静态类型分析。编译器不能保证原始类是真正的类。您将为自己设置ClassCastExceptions的左侧和右侧。
G extends GenericClass<T>>
Class<G extends GenericClass<T>>
Class<GenericClass>
abstract class AbstractClass<T, G extends GenericClass<T>> {
public AbstractClass(Class<? super G> generic, T something) {
}
}