可能重复:
How do you find all subclasses of a given class in Java?
您好,
我想获得一个在运行时用Java实现接口的类列表,这样我就可以进行查找服务而无需对其进行硬编码。有一个简单的方法吗?我不担心。
答案 0 :(得分:24)
简短的回答是否定的。
很长的答案是子类可以通过多种方式存在,这基本上使得无法对它们进行绝对的分类。
你不能在运行时这样做,但是在加载之前你找不到类,你怎么知道它们被加载了?您可以扫描每个JAR和类文件,但这不是确定的。还有像URL类加载器这样的东西。
内部类(静态和非静态)是另一种需要考虑的案例。命名的内部类更容易找到。匿名内部类可能更难找到。
你还必须考虑如果一个类有子类,那么可以在以后创建新的子类。
答案 1 :(得分:5)
你应该使用内置类的Java ServiceLoader。它能够在运行时通过所有已知的服务(接口)实现进行迭代。
如果由于某种原因你不想要它,你可以使用ClassLoader.getSystemResources()迭代所有资源;例如如果您有6次文件/META-INF/com.interface,您将获得6次迭代。
答案 2 :(得分:1)
我总是可以为任何非final类创建一个新的子类,将子类添加到类路径中,并打败你的意图。子类化是一个开放式的命题。
关于你可以做的最好的事情是,对于给定的类路径,你知道子类是什么,为此,你必须扫描类路径中的每个类。
答案 3 :(得分:1)
使用反射相当简单。阅读JavaWorld的这篇文章
http://www.javaworld.com/javaworld/javatips/jw-javatip113.html
答案 4 :(得分:1)
你能够做到的唯一方法就是在类路径中使用包的层次结构,通过反射检查每个类(这会很糟糕,因为你将有效地加载每个类,除非你限制你的搜索到某些包裹)。
这种自动魔法行为的问题在于,如果不运行它就很难量化应用程序,这是一个维护问题。我总是喜欢通过某种配置去注入路径(a-la Spring)传递实例。
答案 5 :(得分:0)
我试图通过这里的答案来推理,所以我可能错了。一个类有关于它的后代或子类的信息是没有意义的,因为在任何时候某人都可以创建一个新的类的子类。然后,您必须重新编译您的类,以便每次都包含此新信息。这对可扩展代码没有意义。类更有可能包含有关其祖先的信息。因此,我能看到的唯一解决方案是让您迭代问题空间中的每个类并检查,但这对您来说可能是一个可怕的解决方案。
答案 6 :(得分:0)
是否要枚举实现特定接口的类或枚举从某个基类派生的类?这是两个不同的问题。据我所知,由于可以在将来的任何时间在PC上创建/安装新的实现,因此很难实现。听起来您正在尝试创建工厂方法来实例化特定实例,并且您不希望在代码中对类名进行硬编码。通常使用枚举所有实现接口的类的配置文件(可以使用数据库)。当新类实现接口时,将它们添加到配置文件中,工厂应该选择新的类名。
答案 7 :(得分:-2)
如果您只从磁盘或URL加载类,则可以扫描类路径并“手动”查找子类。