我正在使用反射遍历类的字段成员,我需要知道List<>子类,泛型类型参数是什么。
给定一个字段的类型是List的子类,我如何以通用的方式告诉List<>的类型参数是
例如:
class X<T> {
List<String> x1; // String
ArrayList<String> x2; // String
SubclassOfArrayListString x3; // String
List<?> x4; // error
List<T> x5; // error
}
class SubclassOfArrayListString extends ArrayList<String> {
// ...
}
注意:我在上面的X中添加了<T>
,以说明可能存在没有正确答案的情况——这与问题无关,只是在回答时需要考虑的问题。
您不能,因为泛型类型信息在编译时丢失(*(。这也是您不能在运行时创建某种泛型类型T
的数组的原因。
在运行时,每个List<T>
都是原始类型List
——你甚至可以在声明为List<String>
的东西上添加一个Integer
,泛型不会也不能阻止这一点[Edit:使用未检查的强制转换或扩展到原始类型的强制转换;这将导致(可抑制的(编译器警告,但不会出错]。
(*(编辑:我学到了一些新的、经过修正的、特定类型的参数(GenericDeclaration的实现者,如Class
、Constructor
、Field
以及Method
的返回、参数和异常类型(将保留在字节码中,并且可以在运行时使用Field.getGenericType((和类似的访问器进行访问。
public class X<T extends List> {
T field;
}
这就是你需要的吗?
阅读本教程关于泛型:泛型教程。这应该会澄清问题。
这个pdf在通配符使用以及扩展ans超级关键字的末尾也有很好的例子。PDF文档
基本上,当您想从容器中读取时,请使用Container<? extends A>
当您想写入容器时,请使用Container<? super A>
。