是否可以获取一个类的所有子类?

发布于 2024-07-26 09:32:59 字数 304 浏览 2 评论 0原文

可能的重复:
如何找到 a 的所有子类Java 中给定的类?

嗨,

我想获取在运行时在 Java 中实现接口的类的列表,这样我就可以进行查找服务,而不必对其进行硬编码。 有没有一种简单的方法可以做到这一点? 我担心不会。

Possible Duplicate:
How do you find all subclasses of a given class in Java?

Hi,

I would like to get a list of classes that implement an interface in Java at runtime so I can do a lookup service without having to hard code it. Is there a simple way of doing this? I fear not.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

弃爱 2024-08-02 09:32:59

最简洁的答案是不。

长的答案是,子类可以通过多种方式存在,这基本上使得不可能明确地找到所有子类。

您无法在运行时执行此操作,但在加载类之前您无法找到它们,您如何知道它们已加载? 您可以扫描每个 JAR 和类文件,但这并不是确定的。 另外还有 URL 类加载器之类的东西。

内部类(静态和非静态)是另一种需要考虑的情况。 命名内部类更容易找到。 匿名内部类可能更难找到。

您还必须考虑,如果一个类有子类,那么稍后可以创建新的子类。

The short answer is no.

The long answer is that subclasses can come into existence in many ways, which basically makes it impossible to categorically find them all.

You can't do it at runtime but you can't find classes until they're loaded and how do you know they're loaded? You could scan every JAR and class file but that's not definitive. Plus there are things like URL class loaders.

Inner classes (static and non-static) are another case to consider. Named inner classes are easier to find. Anonymous inner classes are potentially much more difficult to find.

You also have to consider that if a class has subclasses then new subclasses can be created at a later point.

红焚 2024-08-02 09:32:59

您应该使用内置的 Java ServiceLoader班级。 它能够在运行时迭代所有已知的服务(接口)实现。

如果由于某种原因你不需要它,你可以使用 ClassLoader.getSystemResources() 来迭代所有资源; 例如,如果您有 6 倍的文件 /META-INF/com.interface,您将获得 6 次迭代。

you should use Java ServiceLoader that is a builtin class. It is capable of iterating at runtime over all know service (interface) implementations.

If for some reason you don't want it, you can use ClassLoader.getSystemResources() to iterate over all resources; e.g. if you have 6 times the file /META-INF/com.interface you'll get 6 iterations.

温柔戏命师 2024-08-02 09:32:59

我总是可以为任何非最终类创建一个新的子类,将子类添加到类路径中,并违背您的意图。 子类化是一个开放式的命题。

您能做的最好的事情就是,对于给定的类路径,您知道子类是什么,为此,您必须扫描类路径中的每个类。

I can always create a new subclass for any non-final class, add the subclass to the classpath, and defeat your intent. Subclassing is an open-ended proposition.

About the best you can do is say that for a given classpath, you know what the subclasses are, and to do that, you'd have to scan each class in the classpath.

扎心 2024-08-02 09:32:59

您能够做到这一点的唯一方法是遍历类路径中可用包的包层次结构,通过反射检查每个类(这会很糟糕,因为您将有效地加载每个类,除非您将搜索限制为某些包)。

这种自动神奇行为的问题在于,在不运行应用程序的情况下很难量化应用程序,这是一个令人头痛的维护问题。 我总是更喜欢通过某种配置采用注入路线(a-la Spring)传递实例。

The only way you'd be able to do it is walking the package hierarchy for the packages available in the classpath checking each class via reflection (and that's gonna suck because you'll effectively load every class, unless you restrict your search to certain packages).

The trouble with this sort of auto-magical behavior is that it becomes hard to quantify the application without running it, which is a maintenance headache. I'd always prefer to go the injection route (a-la Spring) passing instances via some sort of configuration.

因为看清所以看轻 2024-08-02 09:32:59

使用反射相当简单。 阅读来自 JavaWorld 的这篇文章

It's fairly simple using reflection. Read this article from JavaWorld.

最冷一天 2024-08-02 09:32:59

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

I am trying to reason through the answer here so I am probably wrong. It would not make sense for a class to have information about its descendants or subclasses because at any point in time someone can create a new subclass of your class. Then you would have to recompile your class to include this new information every time. This does not make sense for extendable code. It is more likely for a class to contain information about its ancestors. So the only solution that I can see is for you to iterate over every class in your problem space and check but this is more than likely a horrible solution for you.

审判长 2024-08-02 09:32:59

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

Do you want to enumerate classes that implement a particular interface or enumerate classes that derive from some base class? These are two different issues. Both as far as I know would be hard to implement since new implementations can be created/installed on a PC at any time in the future. It sounds like you are trying to create a factory method to instantiate a particular instance and you don't want to hard-code the class name in the code. Usually using a config file that enumerates all the classes that implement the interface is the way to go (or a database can be used). As new classes implement the interface, you add them to the config file and the factory should pick up the new class name.

凡间太子 2024-08-02 09:32:59

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

If you only load classes from the disk or from URLs then you can scan the classpath and find subclasses "manually".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文