2010-02-17 116 views
1

我的应用程序由多个JAR文件组成。我想迭代所有的JAR文件,并找到所有继承特定类的类,以便我可以使它们的静态初始化器运行。如何枚举Java中超类的所有子类

我查看了Javadocs的java.lang.ClassLoader,但找不到任何这样做的方法。

我试图实现“产品交易者”模式(http://www.ubilab.com/publications/print_versions/pdf/plop-96-producttrader.pdf),并在抽象超类中使用“自注册”类。超类将有一个HashMap,它映射子类提供的服务和处理该服务的java.lang.Class文件。

问题是一个类直到加载它才运行它的静态初始化器。如果我可以迭代所有的子类,我可以强制每个加载并运行初始化器。

谢谢,拉尔夫

回答

5

这通常不是可以解决的。 ClassLoader不需要能够遍历它可能加载的类。 不能的ClassLoader最简单的例子是,当您从http://基本URL加载类时:HTTP没有提供任何标准方式来枚举任何给定的URL的内容。

更好的实现方法是使用ServiceLoader,让所有的实现类通过jar文件中的简单条目注册自己。

+0

ServiceLoader似乎是相当“重量级”的使用 – Ralph 2010-02-17 14:42:19

+0

@Ralph:真的吗?它看起来正是你想要的。无需执行任何注册。只需向ServiceLoader询问接口的所有实现即可。 – 2010-02-17 14:59:02

+0

我会仔细看看。谢谢。现在,如果我能让ANT自动构建META-INF的东西,它可能是完美的。 – Ralph 2010-02-17 15:24:49

0

如果你真的需要这样做,唯一真正的方法是迭代类路径,扫描类文件的jar和目录,加载该类并查看它的父类。

请注意,一些类将有静态初始化代码,可能有不良副作用,例如,从运行时加载X11类可能会长时间挂起。如果可能,尝试限制将哪些类加载到特定的软件包,例如com.company(当然,你可以通过类文件相对于根路径到类路径项来标识包)。

[注由约阿希姆·绍尔建议的ServiceLoader,或提供类似的机制是一个更好的解决方案框架]

0

这显然不是解决的很干脆。

但是,有解决方案,就像这个Javaworld article中提到的解决方案。

一般来说,它包括探索CLASSPATH中的所有元素。如果它们是jar文件,请探索它们寻找类,加载这些类并查看它们是否扩展了引用基类。 但是,我强烈建议你使用更“成熟”的机制,如IoC或插件架构。

我很明显想着JSPF作为一个例子。