Is it possible to “explore” which objects are defined within an other object via reflection at runtime?

无人久伴 提交于 2019-12-22 12:51:07

问题


Consider this code:

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

How is it possible to "see" the objects defined within object A at runtime? I thought a method within object A with some simple reflection code would be enough, but it seems that the compiler flattens the object hierarchy at compile time and created the following class files:

  • A.class – The class A
  • A$class – The companion object of A
  • A$AA$.class – The AA object
  • A$AB$.class – The AB object
  • A$AC$.class – The AC object

After compilation there is no sign about AA, AB or AC in the companion object A, which would have my magicMethod.

It seems that the ClassLoader class has some related methods to what I plan to do, but all seem to expect the exact String name of the class. Is there a way to ask the ClassLoader to find all class files starting with the class from which this method is called (A$) in the path of that class?


回答1:


The underlying problem is that the JVM has no concept of inner classes. They were added in Java 1.1, but the JVM spec remained completely unchanged between 1.0 and the introduction of invokedynamic (seriously!).

As a bit of a hack, you could always parse the class names and split on $

UPDATE

In order to do this, you'll unfortunately have to scan the classpath.

One of the better known applications of the technique is Apache Commons Discovery: http://commons.apache.org/discovery/ (which is something you could use to make your life easier)

Spring also uses the same approach.




回答2:


The code this.getClass.getDeclaredClasses should return the requested information.

But after experimenting a bit with various tools, it suspect that something is not working correctly here.

I tried various things in Scala with classes inside classes instead of objects and Java sources and judging from the behaviour it should clearly return the expected results but currently it doesn't.

Either I'm fundamentally wrong or scalac might be forgetting to put some bits of metadata into the class files it generates, resulting in incorrect reflection information.

See this bug report.



来源:https://stackoverflow.com/questions/4248521/is-it-possible-to-explore-which-objects-are-defined-within-an-other-object-via

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!