是否可以通过运行时的反射“探索”在另一个对象中定义哪些对象?

时间:2010-11-22 17:53:41

标签: java reflection scala object classloader

考虑以下代码:

object A {
  object AA extends A
  object AB extends A
  object AC extends A
}; class A

如何在运行时“看到”对象A中定义的对象? 我认为使用一些简单的反射代码在object A中的方法就足够了,但似乎编译器在编译时展平了对象层次结构并创建了以下类文件:

  • A.class - A级
  • A$class - A
  • 的配套对象
  • A$AA$.class - AA对象
  • A$AB$.class - AB对象
  • A$AC$.class - AC对象

编译后,伴随对象AA中没有关于ABACA的信号,这将有magicMethod

似乎ClassLoader类与我打算做的事情有一些相关的方法,但似乎都期望该类的确切String名称。有没有办法让ClassLoader找到所有类文件,从该类的路径中调用此方法的类(A$)开始?

2 个答案:

答案 0 :(得分:3)

潜在的问题是JVM没有内部类的概念。它们是在Java 1.1中添加的,但JVM规范在1.0和invokedynamic的引入之间保持完全不变(严重!)。

作为一个黑客攻击,你总是可以解析类名并在$上分开

<强>更新

为了做到这一点,你不幸的是必须扫描类路径。

该技术的一个较着名的应用是Apache Commons Discovery:http://commons.apache.org/discovery/(这可以用来让你的生活更轻松)

Spring也使用相同的方法。

答案 1 :(得分:1)

代码 this.getClass.getDeclaredClasses 应返回所请求的信息。

但是在尝试了各种工具之后,它怀疑某些东西在这里没有正常工作。

我在Scala中尝试了各种类,而不是对象和Java源代码,并从行为判断它应该清楚地返回预期结果,但目前它没有。

要么我从根本上错了,要么scalac可能忘记将一些元数据放入它生成的类文件中,从而导致错误的反射信息。

请参阅this bug report