检查对象是否是给定类名的List的实例

lvi*_*ani 14 java generics instanceof type-erasure

鉴于Object o和a String className = "org.foo.Foo",我想检查是否o是实例List<className>

我试过这个但不会编译:

Class<?> cls = Class.forName(className);
if (o instanceof List<cls>){ // this gives error: cls cannot be resolved to a type
  doSomething();
}
Run Code Online (Sandbox Code Playgroud)

请注意我的输入是Object oString className(请注意类型).

Kon*_*kov 12

这是因为类型擦除.该声明

if (o instanceof List<cls>) {
  doSomething();
}
Run Code Online (Sandbox Code Playgroud)

当擦除列表的泛型类型时,将在运行时执行.因此,没有必要检查instanceof泛型类型.

  • 好的,你在向我解释为什么它不起作用,但我仍然需要找到一种方法来进行检查...... (2认同)
  • @Iviggiani在运行时检查列表中包含的东西类型的唯一方法是拉出一个并查看它.如果列表为空,则完全不可能.这就是为什么你看到很多方法签名看起来像`doSomething(Thing first,Thing ... theRest)`,它允许方法基于`first`显式设置类型,而不是像`doSomething(Thing). ......一切)` (2认同)

Fab*_*eau 9

我认为你可以分两步完成:首先,你检查它是一个列表.

if (o instanceof List)
Run Code Online (Sandbox Code Playgroud)

然后,检查列表中的一个(每个?)成员是否具有给定类型.

for (Object obj : (List) o) {
    if (obj instanceof cls) {
        doSomething();
    }
}
Run Code Online (Sandbox Code Playgroud)


lvi*_*ani 6

好的,我找到了一个方法......这是一个有点脏代码,但它的工作原理:

if (o instanceof List<?>){
  ParameterizedType pt = (ParameterizedType)o.getClass().getGenericSuperclass();
  String innerClass = pt.getActualTypeArguments()[0].toString().replace("class ", "");
  System.out.println(innerClass.equals(className)); // true
}
Run Code Online (Sandbox Code Playgroud)


Vas*_*nth 5

我在我的项目中使用的解决方案。

/**
 * Used to get List of String From Object.
 *
 * 1. used to convert object to list of String.
 * 
 * @param objectList Object List.
 * @return List Of String.
 */
private List<String> getListOfStringFromObject(final Object objectList) {
    List<String> stringList = new ArrayList<>();
    if (objectList instanceof List<?>) {
        for (Object object : (List<?>) objectList) {
            if (object instanceof String) {
                stringList.add((String) object);
            }
        }
    }
    return stringList;
}
Run Code Online (Sandbox Code Playgroud)