我想获得一个参数化类,它能够返回类型为T的对象和T的子对象
这是代码:
import java.lang.reflect.InvocationTargetException;
class A {};
class B extends A {};
public class testGenerics<T extends A> {
T a;
T getA() {
return getA(B.class); // Compilation problem:
//The method getA(Class<T>) in the type testGenerics<T> is not applicable for the arguments (Class<B>)
}
T getA(Class<T> clazz) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
return clazz.getConstructor().newInstance();
}
}
这就是我的想法:
我声明泛型类型T,它扩展了A.因此,我可以从Class clazz创建一个类型为T的实例,扩展为A.
然而,当我决定从B.class(扩展A)获得A时:
getA(B.class)
我收到以下错误:
类型testGenerics&lt;中的方法getA(Class&lt; T&gt;) T>不适用于参数(Class&lt; B&gt;)
这是为什么?我该如何解决?
答案 0 :(得分:1)
您的问题是课程定义class testGenerics<T extends A>
。
这意味着在创建该类的实例时定义了T
,并且A
可以绑定到B
的任何子类 - 可能不是C
而是B.class
等因此,传递T
并不能保证匹配。
要解决此问题,请将<T extends A> A getA(Class<T> clazz) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
return clazz.getConstructor().newInstance();
}
//No generics needed here, since the method above returns A anyways.
//If it'd return T you'd have to change the return type here to B since getA(B.class) binds T to be B now
A getA() throws Exception {
return getA(B.class);
}
的定义置于方法级别:
T
由于方法级别S
隐藏了类级别的定义,您需要对此做一些事情:使用不同的名称(例如{{1}})或删除类级别的定义(它无论如何都没有多大意义。
答案 1 :(得分:0)
这不起作用,因为B
不是T
。是的,B
也扩展了T
,但它不是T
。想象一下,您还有一个类C extends A
并创建一个testGenerics<C>
的实例。您的getA()
方法会实例化B
,但应返回C
。但是,通过一些调整,以下工作正常:
testGenerics<B> tg = new testGenerics<B>();
B b = tg.getA(B.class);
如何解决这个问题取决于你真正想做的事情。例如,这允许您实例化A
的任何子类:
public <S extends A> S getA(Class<S> clazz) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
return clazz.getConstructor().newInstance();
}
但是,您无法在此处使用T
(例如<S extends T>
)。由于T
是参数类型,因此无法保证B
是{延伸T
还是data dataset_1;
input CASENO X;
datalines;
1 100
2 200
3 300
;
data dataset_2;
input CASENO Y;
datalines;
2 200000
3 300000
;
。