Class.isAssignableFrom在某些情况下会给出错误的结果

时间:2014-10-16 07:02:10

标签: java class reflection classloader

我对这种行为感到很困惑。在JBoss 7中,我正在使用@Entity Annotation检索所有类,然后我需要找到实现接口的所有类" BusinessObject"。

这是执行此操作的方法:

     private Set<Class<? extends BusinessObject>> findEntityClasses() {
        //  Alle Klassen holen, die mit "@Entity" annotiert sind. Dabei werden Hibernate- wie auch javax.persistence Annotations genommen
        Reflections reflections = new Reflections("de.something.b4");
        Set<Class<?>> entityClasses = reflections.getTypesAnnotatedWith(Entity.class);

        //Jetzt in das finale Set nur die Klassen kopieren, die von  BusinessObject erben. Weil andere benutzen wir hier nicht!
        Set<Class<? extends BusinessObject>> boClasses = new HashSet<Class<? extends BusinessObject>>();
        try {
          List<Class> l = new ArrayList<Class>(entityClasses);

          for (Class currentClass : l) {
            //Class newCurrentClass = Class.forName(currentClass.getName());
            if (BusinessObject.class.isAssignableFrom(currentClass)) {
              boClasses.add(currentClass);
            }

          }
        } catch (Throwable t) {
          System.out.println(t.getMessage());
        }

        return boClasses;
      }

请注意带有Class.forName()的注释掉的行!

通过此注释,即使currentClass未实现BusinessObject,isAssignableFrom 始终也会返回true。

一旦我删除了对Class.forName()的注释,一旦它被调用,这个类就会发生一些事情,所以对isAssignableFrom的所有后续调用都会按预期返回正确的值。

我确定这有一些原因,Class.forName()对类或类加载器做了一些事情,但我无法弄清楚是什么。有没有人对这种行为有所了解?

1 个答案:

答案 0 :(得分:0)

引用Class.forName()的{​​{3}}:

  

forName("X")的调用会导致名为X的类被初始化。

因此,如果您取消注释Class.forName(currentClass.getName());,它会初始化该类,因此Class.isAssignableFrom()将能够正确测试该类是否实现BusinessObjectReflections可能无法初始化它们)。