java 是否有可能得到一个类的所有子类?[副本]

tez616oj  于 2023-04-28  发布在  Java
关注(0)|答案(8)|浏览(115)

此问题已在此处有答案

13年前就关门了

可能重复:

How do you find all subclasses of a given class in Java?
你好
我想得到一个在运行时实现Java接口的类列表,这样我就可以做一个查找服务,而不必硬编码。有没有一个简单的方法来做到这一点?恐怕没有。

35g0bw71

35g0bw711#

如果您只从磁盘或URL加载类,那么您可以扫描类路径并“手动”查找子类。

pod7payv

pod7payv2#

简短的回答是否定的。
详细的答案是子类可以以多种方式存在,这基本上使得不可能明确地找到所有子类。
你不能在运行时这样做,但是你不能找到类,直到它们被加载,你怎么知道它们被加载了?您可以扫描每个JAR和类文件,但这不是确定的。另外还有一些类似URL类加载器的东西。
内部类(静态和非静态)是另一种需要考虑的情况。命名的内部类更容易找到。匿名内部类可能更难找到。
您还必须考虑,如果一个类有子类,那么可以在稍后创建新的子类。

bcs8qyzn

bcs8qyzn3#

你应该使用Java ServiceLoader,它是一个内置类。它能够在运行时迭代所有已知的服务(接口)实现。
如果出于某种原因你不想要它,你可以使用ClassLoader。getSystemResources()迭代所有资源;例如,如果你有6倍的文件/META-INF/com。你会得到6次迭代。

lp0sw83n

lp0sw83n4#

我总是可以为任何非final类创建一个新的子类,将子类添加到类路径中,并挫败您的意图。子类化是一个开放式的命题。
对于给定的类路径,您最多只能说知道子类是什么,要做到这一点,您必须扫描类路径中的每个类。

dm7nw8vv

dm7nw8vv5#

唯一的方法是遍历类路径中可用包的包层次结构,通过反射检查每个类(这会很糟糕,因为你会有效地加载每个类,除非你将搜索限制在某些包上)。
这种自动神奇的行为的问题在于,如果不运行应用程序,就很难量化它,这是一个令人头疼的维护问题。我总是更喜欢通过某种配置来传递示例的注入路线(a-la Spring)。

ddhy6vgd

ddhy6vgd6#

使用反射是相当简单的。阅读JavaWorld中的this article

oyjwcjzk

oyjwcjzk7#

我试图通过这里的答案推理,所以我可能是错的。对于一个类来说,拥有关于它的后代或子类的信息是没有意义的,因为在任何时候都有人可以创建一个新的子类。然后,您必须重新编译类,每次都包含这些新信息。这对可扩展代码没有意义。一个类更有可能包含有关其祖先的信息。所以我能看到的唯一解决方案就是迭代问题空间中的每个类并进行检查,但这对你来说可能是个糟糕的解决方案。

alen0pnh

alen0pnh8#

是枚举实现特定接口的类,还是枚举从某个基类派生的类?这是两个不同的问题。据我所知,这两者都很难实现,因为未来任何时候都可以在PC上创建/安装新的实现。这听起来像是您试图创建一个工厂方法来示例化一个特定的示例,并且您不想在代码中硬编码类名。通常使用一个枚举所有实现接口的类的配置文件是一种方法(或者可以使用数据库)。当新的类实现接口时,您将它们添加到配置文件中,工厂应该选择新的类名。

相关问题