繁体   English   中英

在Java中的List中获取泛型类型

[英]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的类型。 请查看此内容以获取更多详 但是如果列表不为空,您可以从列表中获取一个元素,并且可以找到使用instanceofif 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM