猿问

在运行时,查找Java应用程序中扩展基类的所有类

在运行时,查找Java应用程序中扩展基类的所有类

我想做这样的事:

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() );

所以,我想看看我的应用程序世界中的所有类,当我找到一个从动物界下来的类时,我想创建一个新的对象,并将它添加到列表中。这允许我添加功能,而不必更新内容列表。我可以避免下列情况:

List<Animal> animals = new ArrayList<Animal>();animals.add( new Dog() );animals.add( new Cat() );animals.add( new Donkey() );...

使用上面的方法,我可以简单地创建一个新的类,这个类扩展了Properties,它将自动被获取。

更新日期:2008年10月16日上午9时。太平洋标准时间:

现在有几个库可以在这方面提供帮助。回答 org.反射看上去不错。也类图来自卢克·和记黄埔回答看上去很有趣。答案中还有更多的可能性。

另一种陈述我想要的东西的方法是:我的动物类中的一个静态函数查找并实例化了所有继承自动物的类-没有任何进一步的配置/编码。如果我必须进行配置,那么我最好还是将它们实例化在动物类中。我理解这一点,因为Java程序只是.class文件的松散联合,这正是它的方式。

有趣的是,这似乎是相当琐碎在C#。


HUX布斯
浏览 279回答 3
3回答

呼啦一阵风

我用org.反射:Reflections&nbsp;reflections&nbsp;=&nbsp;new&nbsp;Reflections("com.mycompany");&nbsp;&nbsp;&nbsp;&nbsp; Set<Class<?&nbsp;extends&nbsp;MyInterface>>&nbsp;classes&nbsp;=&nbsp;reflections.getSubTypesOf(MyInterface.class);另一个例子:public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;throws&nbsp;IllegalAccessException,&nbsp;InstantiationException&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;Reflections&nbsp;reflections&nbsp;=&nbsp;new&nbsp;Reflections("java.util"); &nbsp;&nbsp;&nbsp;&nbsp;Set<Class<?&nbsp;extends&nbsp;List>>&nbsp;classes&nbsp;=&nbsp;reflections.getSubTypesOf(java.util.List.class); &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(Class<?&nbsp;extends&nbsp;List>&nbsp;aClass&nbsp;:&nbsp;classes)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(aClass.getName()); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(aClass&nbsp;==&nbsp;ArrayList.class)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;list&nbsp;=&nbsp;aClass.newInstance(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.add("test"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(list.getClass().getName()&nbsp;+&nbsp;":&nbsp;"&nbsp;+&nbsp;list.size()); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;}}

梵蒂冈之花

从面向方面的角度来考虑这一点;您真正想要做的是了解所有在运行时扩展了动物类的类。(我认为这比标题更准确地描述了您的问题;否则,我认为您没有运行时问题。)因此,我认为您想要的是创建一个基类的构造函数(动物),它将当前类的类型添加到静态数组中(我自己喜欢ArrayList,但每个类都是自己的)。因此,大致如此;public&nbsp;abstract&nbsp;class&nbsp;Animal &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;static&nbsp;ArrayList<Class>&nbsp;instantiatedDerivedTypes; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Animal()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class&nbsp;derivedClass&nbsp;=&nbsp;this.getClass(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!instantiatedDerivedClass.contains(derivedClass))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instantiatedDerivedClass.Add(derivedClass); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;}当然,要初始化实例化派生类,需要一个静态构造函数.我想这能做你想做的事。请注意,这是与执行路径相关的;如果您有一个派生自动物的Dog类,而该类从未被调用过,那么您将不会将它包含在动物类列表中。
随时随地看视频慕课网APP

相关分类

Java
我要回答