我有;
List<String> stringList = new ArrayList<String>();
List<Integer> integerList = new ArrayList<Integer>();
是否有(简单)方法检索列表的泛型类型?
我有;
List<String> stringList = new ArrayList<String>();
List<Integer> integerList = new ArrayList<Integer>();
是否有(简单)方法检索列表的泛型类型?
当前回答
你也可以对方法参数做同样的事情:
Method method = someClass.getDeclaredMethod("someMethod");
Type[] types = method.getGenericParameterTypes();
//Now assuming that the first parameter to the method is of type List<Integer>
ParameterizedType pType = (ParameterizedType) types[0];
Class<?> clazz = (Class<?>) pType.getActualTypeArguments()[0];
System.out.println(clazz); //prints out java.lang.Integer
其他回答
查找一个字段的泛型类型:
((Class)((ParameterizedType)field.getGenericType()).getActualTypeArguments()[0]).getSimpleName()
使用反射来获取这些字段,然后你可以做:Field。genericType来获取包含generic信息的类型。
有同样的问题,但我使用instanceof代替。是这样做的:
List<Object> listCheck = (List<Object>)(Object) stringList;
if (!listCheck.isEmpty()) {
if (listCheck.get(0) instanceof String) {
System.out.println("List type is String");
}
if (listCheck.get(0) instanceof Integer) {
System.out.println("List type is Integer");
}
}
}
这涉及到使用未检查的类型转换,所以只有在知道它是一个列表以及它可以是什么类型时才这样做。
通常不可能,因为List<String>和List<Integer>共享相同的运行时类。
不过,您可能能够反映包含列表的字段的声明类型(如果声明的类型本身并不引用您不知道其值的类型参数)。
集合的泛型类型应该只在它实际上有对象时才重要,对吗?所以这样做不是更简单吗:
Collection<?> myCollection = getUnknownCollectionFromSomewhere();
Class genericClass = null;
Iterator it = myCollection.iterator();
if (it.hasNext()){
genericClass = it.next().getClass();
}
if (genericClass != null) { //do whatever we needed to know the type for
在运行时没有泛型类型这样的东西,但运行时内部的对象保证与声明的泛型是相同的类型,因此在处理它之前测试项的类非常容易。
您可以做的另一件事是简单地处理列表以获得正确类型的成员,忽略其他成员(或以不同的方式处理它们)。
Map<Class<?>, List<Object>> classObjectMap = myCollection.stream()
.filter(Objects::nonNull)
.collect(Collectors.groupingBy(Object::getClass));
// Process the list of the correct class, and/or handle objects of incorrect
// class (throw exceptions, etc). You may need to group subclasses by
// filtering the keys. For instance:
List<Number> numbers = classObjectMap.entrySet().stream()
.filter(e->Number.class.isAssignableFrom(e.getKey()))
.flatMap(e->e.getValue().stream())
.map(Number.class::cast)
.collect(Collectors.toList());
这将为您提供一个所有项目的列表,这些项目的类都是Number的子类,然后您可以根据需要对其进行处理。其余的项目被过滤到其他列表中。因为它们在地图中,所以您可以根据需要处理它们,或者忽略它们。
如果你想完全忽略其他类的项目,它会变得简单得多:
List<Number> numbers = myCollection.stream()
.filter(Number.class::isInstance)
.map(Number.class::cast)
.collect(Collectors.toList());
你甚至可以创建一个实用工具方法来确保列表只包含那些匹配特定类的项:
public <V> List<V> getTypeSafeItemList(Collection<Object> input, Class<V> cls) {
return input.stream()
.filter(cls::isInstance)
.map(cls::cast)
.collect(Collectors.toList());
}