是否有可能获得实现接口的所有类?

时间:2013-03-09 06:02:58

标签: java reflection subclass

我可以用反射或类似的东西来做吗?

1 个答案:

答案 0 :(得分:9)

没有100%可靠的方法来做你想做的事。原因是因为类加载在Java中是如何工作的。

Java中的类是“按需”加载的。第一次在代码中引用类(静态或动态)时,JVM将使用当前的类加载器并尝试加载它。 ClassLoader没有给出可以从中加载的所有类的方法,因此你不能迭代类。

有一些不可靠的解决方法。例如,如果您知道您的ClassLoader只会从特定目录或特定JAR文件中加载类,则可以使用与文件系统相关的类来查找可用的“.class”文件,然后就可以了加载所有东西(这需要花费时间并且会消耗很多你的PermGen,这可能是一个问题 - 记住你不能轻松卸载一个类!(除非你做一些ClassLoader魔术)),并使用反射来过滤实现你的类接口

此解决方法的问题在于,如果您更改部署,它很可能会停止工作。例如,如果您开始部署JAR文件,那么稍后您决定使用将处理WAR文件的servlet容器,您的代码可能不再起作用。

如果您真的想尝试这种方法,那么有一个名为Reflections的项目可能会有用。

我实施过的最可靠的方法是使用注释处理器。您编写注释,注释您的接口,并编写一些代码,这些代码将在编译时由编译器执行,它将收集实现您的接口的类并将其名称保存在资源文件中。然后你用一个方法编写一个类来读取该文件,并为该资源文件中列出的每个类名提供一个Class对象。

这种方法的问题在于,只列出在我的构建过程中编译的类(即,如果您发布带有接口的库并希望其他人实现您的接口,这种方法将没有用,因为你的代码永远不会知道其他人项目中的类。如果这对你来说足够了,就像对我来说一样,这个解决方案可以完美运行。我可以在带有WAR(爆炸或非爆炸)部署的Servlet容器中,在可执行的jar中使用它,无论如何。它会一直有效。