考虑以下代码:
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
中没有关于AB
,AC
或A
的信号,这将有magicMethod
。
似乎ClassLoader
类与我打算做的事情有一些相关的方法,但似乎都期望该类的确切String名称。有没有办法让ClassLoader找到所有类文件,从该类的路径中调用此方法的类(A$
)开始?
答案 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。