【问题标题】:Is it possible to get all classes that implementing an interface? [duplicate]是否可以获得所有实现接口的类? [复制]
【发布时间】:2013-02-24 19:30:59
【问题描述】:

我可以用反射或类似的方法来做吗?

【问题讨论】:

  • 为什么有这么多反对票?这是一个完全有效的问题!
  • 试试THIS
  • @BrunoReis - 当您将鼠标悬停在向下投票箭头上时,它会显示:“这个问题没有显示任何研究工作”。我认为这是一个有效的评估。
  • 右侧显示了很多相关问题。 @BrunoReis

标签: java reflection subclass


【解决方案1】:

没有 100% 可靠的方式来做你想做的事。原因在于类加载在 Java 中的工作方式。

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

有一些不可靠的解决方法。例如,如果您知道您的 ClassLoader 只会从特定目录或特定 JAR 文件中加载类,那么您可以使用与您的文件系统相关的类来查找可用的“.class”文件,然后您可以加载所有内容(这需要时间并且会消耗大量 PermGen,这可能是个问题——记住你不能轻易卸载一个类!(除非你做了一些 ClassLoader 魔法)),并使用反射来过滤实现你的类界面。

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

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

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

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

【讨论】:

  • 真的吗?我的 IDE 做得很好......
  • @BrianRoach,哦,真的吗?现在,您要么要求您的 IDE 列出您的类,然后您 CTRL+C 列出列表,CTRL+V 在代码中的某处(并在每次添加新类时手动更新),或者您的 IDE 完全知道它的事实对您正在运行的代码无用。或者您尝试一种并非 100% 可靠的方法(遍历您的文件系统或在 JAR 文件中查找 .class 文件,或使用不同的方法,例如我建议的方法)。具体来说,IDE 知道它正在处理文件系统,因此它可以轻松地对文件进行迭代。 100% 可靠。在运行时无用。
  • 或者你可以直接按 ctrl+T 并允许像 eclipse 这样的 IDE 向你显示类层次结构。目前尚不清楚 OP 是否需要在运行时/编译时提供解决方案。
  • @DeepakBala,因为他提到“使用反射”,我很清楚他正在寻找运行时的解决方案(如果不是这种情况,正如 Brian Roach 所说,使用你的 IDE ,你就完成了)。
  • @BrianRoach 很可能您的 IDE 不仅在扫描类文件(它通过链接/包含和编译知道),而且还在解析源代码。例如,Netbeans 实际上链接到 rt.jar。尝试对动态加载的类做同样的事情,我敢打赌你的 IDE 不会知道这些;)
猜你喜欢
  • 2010-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-15
  • 1970-01-01
  • 2016-02-21
  • 2018-08-24
  • 2015-12-23
相关资源
最近更新 更多