在运行时,查找 Java 应用程序中扩展基类的所有类 [英] At runtime, find all classes in a Java application that extend a base class
问题描述
我想做这样的事情:
List<Animal> animals = new ArrayList<Animal>();
for( Class c: list_of_all_classes_available_to_my_app() )
if (c is Animal)
animals.add( new c() );
因此,我想查看应用程序 Universe 中的所有类,当我找到一个来自 Animal 的类时,我想创建一个该类型的新对象并将其添加到列表中.这使我无需更新事物列表即可添加功能.我可以避免以下情况:
So, I want to look at all of the classes in my application's universe, and when I find one that descends from Animal, I want to create a new object of that type and add it to the list. This allows me to add functionality without having to update a list of things. I can avoid the following:
List<Animal> animals = new ArrayList<Animal>();
animals.add( new Dog() );
animals.add( new Cat() );
animals.add( new Donkey() );
...
通过上述方法,我可以简单地创建一个扩展 Animal 的新类,它会自动被选中.
With the above approach, I can simply create a new class that extends Animal and it'll get picked up automatically.
更新:2008 年 10 月 16 日上午 9:00 太平洋标准时间:
UPDATE: 10/16/2008 9:00 a.m. Pacific Standard Time:
这个问题引起了很多很好的回应——谢谢.从回复和我的研究中,我发现我真正想做的事情在 Java 下是不可能的.有一些方法,例如 ddimitrov 的 ServiceLoader 机制可以工作——但它们对于我想要的东西来说非常繁重,我相信我只是将问题从 Java 代码转移到外部配置文件. 更新 5/10/19(11 年后!)根据@IvanNik 的 answer<,现在有几个库可以帮助解决这个问题/a> org.reflections 看起来不错.还有来自@Luke Hutchison 的 ClassGraph9648">答案 看起来很有趣.答案中还有更多的可能性.
This question has generated a lot of great responses -- thank you. From the responses and my research, I've found that what I really want to do is just not possible under Java. There are approaches, such as ddimitrov's ServiceLoader mechanism that can work -- but they are very heavy for what I want, and I believe I simply move the problem from Java code to an external configuration file. Update 5/10/19 (11 years later!) There are now several libraries that can help with this according to @IvanNik's answer org.reflections looks good. Also ClassGraph from @Luke Hutchison's answer looks interesting. There are several more possibilities in the answers as well.
另一种表达我想要的方式:我的 Animal 类中的静态函数查找并实例化从 Animal 继承的所有类——无需任何进一步的配置/编码.如果我必须配置,我不妨在 Animal 类中实例化它们.我理解这是因为 Java 程序只是 .class 文件的松散联合,所以它就是这样.
Another way to state what I want: a static function in my Animal class finds and instantiates all classes that inherit from Animal -- without any further configuration/coding. If I have to configure, I might as well just instantiate them in the Animal class anyway. I understand that because a Java program is just a loose federation of .class files that that's just the way it is.
有趣的是,这似乎是 C# 中的相当简单.
Interestingly, it seems this is fairly trivial in C#.
推荐答案
我使用 org.reflections:
Reflections reflections = new Reflections("com.mycompany");
Set<Class<? extends MyInterface>> classes = reflections.getSubTypesOf(MyInterface.class);
另一个例子:
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
Reflections reflections = new Reflections("java.util");
Set<Class<? extends List>> classes = reflections.getSubTypesOf(java.util.List.class);
for (Class<? extends List> aClass : classes) {
System.out.println(aClass.getName());
if(aClass == ArrayList.class) {
List list = aClass.newInstance();
list.add("test");
System.out.println(list.getClass().getName() + ": " + list.size());
}
}
}
这篇关于在运行时,查找 Java 应用程序中扩展基类的所有类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!