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

时间:2010-11-11 14:15:27

标签: java generics

我有以下功能:


    public <T> void putList(String key, List<T> lst){
          if (T instanceof String) {
          // Do something       
          }
          if (T instanceof Integer) {
          // Do something   
          }
    }

在这个功能中,我想知道&lt; T&gt;是字符串还是整数,所以我想知道是否有办法发现它的类型?我使用了上面的代码,但它生成了错误

提前谢谢。

7 个答案:

答案 0 :(得分:9)

由于类型信息被删除,您无法找到T的类型。查看this了解更多详情。但是,如果列表不为空,您可以从列表中获取一个元素,并可以使用instanceofif else

查找

答案 1 :(得分:9)

由于erasure,Java无法实现。大多数人做的是添加类型令牌。例如:

public <T> void putList(String key, List<T> list, Class<T> listElementType) {
}

在某些情况下,反射可以在type参数中获得,但它适用于您已预先设置type参数的情况。例如:

public class MyList extends List<String> {
    private List<String> myField;
}

在这两种情况下,反射可以确定List的类型为String,但反射无法确定您的情况。您必须使用类似令牌的其他方法。

答案 2 :(得分:1)

由于erasure,无法确定这一点,这意味着参数未存储在代码中。但是,您可以传递一个额外的参数来指定列表的类型:

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   
      }
  }
}

答案 3 :(得分:1)

泛型称为“擦除”,因为它们仅在编译时存在,并由编译器删除。因此,无法确定通用类型的集合。对非空列表执行此操作的唯一方法是获取第一个元素并确定其类型。

这几乎与DJClayworth建议的解决方案相同,但我认为没有必要检查列表中的每个元素。如果您确定列表是使用泛型(new ArrayList()或new LinkedList()等)创建的,则所有元素都保证属于同一类型。

答案 4 :(得分:0)

如果要运行对象的功能,可以执行以下操作:

Your meeting request was declined. The invitation was declined because it occurred in the past.

答案 5 :(得分:-1)

使用instanceof运算符。

也就是说,通用操作应该是通用的,因此要小心改变基于类型的行为。

答案 6 :(得分:-1)

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);
    }
}