【发布时间】:2014-12-11 10:45:43
【问题描述】:
我真的对这种行为感到困惑。在 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 always 也会返回 true。
只要我删除 Class.forName() 上的注释,一旦调用它,这个类就会发生一些事情,因此所有后续调用 isAssignableFrom 都会按预期返回正确的值。
我确定这是有原因的,Class.forName() 对类或类加载器做了一些事情,但我不知道是什么。有人知道这种行为吗?
【问题讨论】:
-
尝试使用 Class.forName( currentClass.getName(), false, this.getClass().getClassloader() ),看看是否仍然会导致问题。
-
这是一个非常有趣的问题。使用
Class.forName时,请记住它还完全初始化了一个类。所以,@Smith_61 的评论可能会引向正确的方向。 -
@Seelenvirtuose 这是我的想法。反射在未初始化的类对象中返回,并且 JVM 错误在此上下文中使用时无法初始化类。您使用的是什么 JVM/操作系统?我无法在 JVM 8、Windows 8.1 x64 上复制。
-
感谢您的回复和抱歉 - 之前发布的代码即使 with Class.forName() 也不起作用 - 我将其剥离了一点以美化,但可能有一些东西丢失了。我用我的实际代码编辑了原始帖子。有了这个,我可以重现行为。我已经尝试过初始化 false,但即使是 false - 在调用 Class.forName() 之后一切都按预期工作。另外——如果有趣的话——BusinessObject 类和此代码驻留在部署在耳朵中的不同 jar 中。
-
@philli 您的操作系统/JVM 信息是什么?
标签: java class reflection classloader