[英]Get type of generic type inside a List in Java
我有以下功能:
public <T> void putList(String key, List<T> lst){
if (T instanceof String) {
// Do something
}
if (T instanceof Integer) {
// Do something
}
}
在这个函数里面,我想知道<T>是String还是Integer,所以我想知道是否有办法发现它的类型? 我使用上面的代码,但它生成错误
先感谢您。
因为类型信息被删除,您无法找到T
的类型。 请查看此内容以获取更多详 但是如果列表不为空,您可以从列表中获取一个元素,并且可以找到使用instanceof
和if else
由于擦除,在Java中是不可能的。 大多数人做的是添加类型令牌。 例:
public <T> void putList(String key, List<T> list, Class<T> listElementType) {
}
在某些情况下,反射可以在类型参数中获得,但它适用于您已预先设置类型参数的情况。 例如:
public class MyList extends List<String> {
private List<String> myField;
}
在这两种情况下,反射可以确定List的类型为String,但反射无法确定您的情况。 您必须使用类似令牌的其他方法。
由于擦除 ,无法确定这一点,这意味着参数未存储在代码中。 但是,您可以传递一个额外的参数来指定列表的类型:
public <T> void putList(String key, List<T> lst, Class<T> listElementType) {
}
或者您可以在运行时确定每个元素的类型:
public <T> void putList(String key, List<T> lst){
for (Object elem:lst) {
if (elem instanceof String) {
// Do something
}
if (elem instanceof Integer) {
// Do something
}
}
}
泛型称为“擦除”,因为它们仅在编译时存在,并由编译器删除。 因此,无法确定通用类型的集合。 对非空列表执行此操作的唯一方法是获取第一个元素并确定其类型。
这几乎与DJClayworth建议的解决方案相同,但我认为没有必要检查列表中的每个元素。 如果您确定列表是使用泛型(new ArrayList()或new LinkedList()等)创建的,则所有元素都保证属于同一类型。
如果要运行对象的功能,可以执行以下操作:
public <T> void putList(String key, List<T> lst){
for(T object : lst){
if(object instanceof String) {
doSomething(((String)object).doForString())
}
if(object instanceof Integer) {
doSomething(((Integer)object).doForInteger())
}
}
}
使用instanceof运算符。
也就是说,通用操作应该是通用的,因此要小心改变基于类型的行为。
Type genericType = lst.getType();
if(genericType instanceof ParameterizedType){
ParameterizedType aType = (ParameterizedType) genericType;
Type[] fieldArgTypes = aType.getActualTypeArguments();
for(Type fieldArgType : fieldArgTypes){
Class fieldArgClass = (Class) fieldArgType;
System.out.println("fieldArgClass = " + fieldArgClass);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.