我有;

List<String> stringList = new ArrayList<String>();
List<Integer> integerList = new ArrayList<Integer>();

是否有(简单)方法检索列表的泛型类型?


当前回答

通常不可能,因为List<String>和List<Integer>共享相同的运行时类。

不过,您可能能够反映包含列表的字段的声明类型(如果声明的类型本身并不引用您不知道其值的类型参数)。

其他回答

一个小的帮助方法:

/**
 * Get type of collection field.
 *
 * @param aClass A class containing collection.
 * @param collectionName A collection field name.
 */
@SneakyThrows
public static Class<?> getCollectionType(Class<?> aClass, String collectionName) {
  Field field = aClass.getDeclaredField(collectionName);
  ParameterizedType genericType = (ParameterizedType) field.getGenericType();
  return (Class<?>) genericType.getActualTypeArguments()[0];
}

查找一个字段的泛型类型:

((Class)((ParameterizedType)field.getGenericType()).getActualTypeArguments()[0]).getSimpleName()

通常不可能,因为List<String>和List<Integer>共享相同的运行时类。

不过,您可能能够反映包含列表的字段的声明类型(如果声明的类型本身并不引用您不知道其值的类型参数)。

正如其他人所说,唯一正确的答案是否定的,该类型已被删除。

如果列表的元素数目非零,则可以研究第一个元素的类型(例如,使用它的getClass方法)。这不会告诉您列表的泛型类型,但可以合理地假设泛型类型是列表中类型的某个超类。

我不提倡这种方法,但在遇到困难时,它可能会有用。

我找到了一个非常适合我的答案。

class ArrayListString extends ArrayList<String> {}
class ArrayListInteger extends ArrayList<Integer> {}

ArrayListString als = new ArrayListString();
ArrayListInteger ali = new ArrayListInteger();

void whatType(Object a) {
    if (a instanceof ArrayListString)
        System.out.println("ArrayListString");
    else if (a instanceof ArrayListInteger)
        System.out.println("ArrayListInteger");
}

whatType(als);
whatType(ali);

Als和ali将像它们的泛型一样工作。

这段代码所做的是将泛型类型转换为常规Java类型。在Java中,可以使用instanceof检测常规类型。