This question already has answers here:
Checking Java Collection Generic Type for an Empty Collection

(4个答案)



How do I get a class instance of generic type T?

(21个回答)


4年前关闭。




我有以下方法:

public <T> void meth(T t){

}


内部方法中,我需要检查t是否为String的集合(List<String>Set<String>等)

我知道我可以使用反射来做到这一点,但我不确定如何确定。

附言

我相信org.springframework.core.GenericTypeResolver#resolveTypeArgument需要解决此问题,但我不知道要传递哪些参数。

我已经阅读过该主题https://stackoverflow.com/a/9202329/2674303,但是我不知道如何在我的情况下应用它

最佳答案

通过反射,您可以测试tCollection,但是由于类型擦除,您无法检查它是否是Collection<String>

这仍然是如何检查tCollection的方法。

public <T> void meth(T t){
  if(Collection.class.isAssignableFrom(t.getClass())) {
    System.out.println(true);
  } else {
    System.out.println(false);
  }


请注意,您仍然可以测试集合中的各个元素,但是如果需要这样做,则可能存在设计问题。

在回答gstackoverflow的评论时:

我检查了this link,我需要一些时间来理解它。简短的答案是“您不能,因为在编译时泛型类型已被Object替换。” (类型擦除),但是您仍然可以获得编译时可用的信息,根据您的用例,这些信息就足够了。

例如 :

private static Type[] getTypes(Object object) {
  return ((ParameterizedType)object.getClass().getGenericSuperclass()).getActualTypeArguments();
}


有时,它将是无用的:

Map<Integer, String> object = new HashMap<>();
for (Type actualTypeArgument : getTypes(object)) {
  System.out.println(actualTypeArgument);
}


答:

K
V


(实际上,在编译时,您没有有关Map<K, V>通用类型的任何其他信息)。

但是有时候,它可能会有用:

public class IntegerList extends ArrayList<Integer> {
}

for (Type actualTypeArgument : getTypes(new IntegerList())) {
  System.out.println(actualTypeArgument);
}


答:

class java.lang.Integer


之所以可以使用它,是因为在编译时,编译器知道IntegerListList<Integer>

换句话说,您可以访问编译时可用的信息,但不能访问运行时已知的信息。

09-28 12:25