【问题标题】:Check if an object is instance of List of given class name检查对象是否是给定类名列表的实例
【发布时间】:2014-07-28 20:24:51
【问题描述】:

给定一个Object o 和一个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();
}

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

【问题讨论】:

  • 泛型为erased at runtime。你试图做的似乎是不可能的。你能解释一下你为什么要这样做吗?也许是XY problem
  • 我在使用 SAX 解析 XML 时动态实例化对象

标签: java generics instanceof type-erasure


【解决方案1】:

因为Type Erasure。声明

if (o instanceof List<cls>) {
  doSomething();
}

将在运行时执行,此时列表的泛型类型将被擦除。因此,没有必要检查 instanceof generic-type。

【讨论】:

  • 好吧,你在解释为什么它不起作用,但我仍然需要找到一种方法来进行检查......
  • @Iviggiani 你不能。程序无法弄清楚正在使用什么泛型,因为泛型在运行时不存在。
  • @Iviggiani 在运行时检查列表中包含的事物类型的唯一方法是拉出一个并查看它。如果列表是空的,那是完全不可能的。这就是为什么你会看到很多看起来像doSomething(Thing first, Thing... theRest) 的方法签名,它允许方法根据first 显式设置类型,而不是像doSomething(Thing... everything) 这样的东西。
【解决方案2】:

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

if (o instanceof List)

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

for (Object obj : (List) o) {
    if (obj instanceof cls) {
        doSomething();
    }
}

【讨论】:

    【解决方案3】:

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

    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
    }
    

    【讨论】:

    • 试过这个来断言 MyObject 的类型,但无法让它工作。尝试转换为 ParameterizedType 时会引发类转换异常。
    【解决方案4】:

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

    /**
     * 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;
    }
    

    【讨论】:

      【解决方案5】:
      public class Main{
      
          public static void main(String[] args){
              String str = "";
              int oi = 0;
              char c = 'a';
              Main af = new Main();
              checkType(str);
              checkType(oi);
              checkType(c);
              checkType(af);
          }
      
          public static void checkType(Object o){
              String str = o.getClass().getName();
              switch(str){
                  case "java.lang.String":
                      System.out.println("String");
                      break;  
                  case "java.lang.Integer":
                      System.out.println("Integer");
                      break;
                  case "java.lang.Character":
                      System.out.println("Char");
                      break;
                  case "Main":
                      System.out.println("Main");
                      break;
                  default :
                      System.out.println("Something else:" + str);
                      break;
              }
          }
      
      }
      

      注意>只需将每个case 中的public static boolean checkType(Object o) 更改为return true,这不是默认值。

      【讨论】:

        【解决方案6】:

        如果你想做的是这样的:

        class XXX implements InterfaceX {
            @Override
            public void methedX() { }
        }
        
        interface InterfaceX {
            void methedX();
        }
        List<XXX> x = new ArrayList<>();
        
        if(x instanceOf List<InterfaceX>) {
            data.get(0).methedX();
        }
        

        您可以尝试使用以下模板:

        class TypeHelper <T extends InterfaceX> {
            List<T> data;
            TypeHelper (List<T> data) {
                this.data = data;
            }
        
            public void func() {
                data.get(0).methedX();
            }
        }
        
        TypeHelper helper = new TypeHelper<XXX>(x);
        helper.func();
        

        【讨论】:

          猜你喜欢
          • 2017-12-06
          • 2012-11-26
          • 2015-08-03
          • 1970-01-01
          • 1970-01-01
          • 2021-11-20
          • 2013-05-17
          相关资源
          最近更新 更多