【发布时间】:2010-09-17 08:40:30
【问题描述】:
我想做这样的事情:
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 的类时,我想创建一个该类型的新对象并将其添加到列表中。这使我无需更新事物列表即可添加功能。我可以避免以下情况:
List<Animal> animals = new ArrayList<Animal>();
animals.add( new Dog() );
animals.add( new Cat() );
animals.add( new Donkey() );
...
通过上述方法,我可以简单地创建一个扩展 Animal 的新类,它会被自动拾取。
更新:2008 年 10 月 16 日上午 9:00 太平洋标准时间:
这个问题得到了很多很好的回应——谢谢。 从回复和我的研究中,我发现我真正想做的事情在 Java 下是不可能的。有一些方法可以工作,例如 ddimitrov 的 ServiceLoader 机制 - 但它们对于我想要的来说非常繁重,我相信我只是将问题从 Java 代码转移到外部配置文件。 更新 5 /10/19(11 年后!)根据@IvanNik 的answer org.reflections 看起来不错,现在有几个库可以帮助解决这个问题。同样来自@Luke Hutchison 的answer 的ClassGraph 看起来很有趣。答案中还有更多的可能性。
另一种表达我想要的方式:我的 Animal 类中的静态函数查找并实例化从 Animal 继承的所有类——无需任何进一步的配置/编码。如果我必须配置,我还不如在 Animal 类中实例化它们。我理解这是因为 Java 程序只是 .class 文件的松散联合,所以它就是这样。
有趣的是,这似乎是 C# 中的 fairly trivial。
【问题讨论】:
-
找了一阵子,看来这是Java中难以破解的难题。这是一个包含一些信息的线程:forums.sun.com/thread.jspa?threadID=341935&start=15 其中的实现比我需要的要多,我想我现在只坚持第二个实现。
-
在 C# 中执行此操作的链接没有显示任何特别之处。 C# 程序集等同于 Java JAR 文件。它是编译的类文件(和资源)的集合。该链接显示了如何从单个程序集中获取类。使用 Java 几乎可以轻松地做到这一点。您的问题是您需要查看所有 JAR 文件和真正的松散文件(目录);您需要对 .NET 执行相同的操作(搜索某种或各种 PATH)。
标签: java reflection inheritance