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

发布于 2021-02-02 22:57:33

我想做这样的事情:

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的新类,它将自动被拾取。

更新:10/16/2008 9:00 AM太平洋标准时间:

这个问题引起了很多反响-谢谢。 从响应和研究中,我发现我真正想做的事在Java下是不可能的。有一些方法可以使用,例如ddimitrov的ServiceLoader机制,但是对于我想要的东西,它们非常繁琐,我相信我只是将问题从Java代码转移到了外部配置文件中。 更新5/10/19(11年后!)根据@IvanNik的回答 ,现在有几个库可以帮助解决此问题。org.reflections看起来不错。此外ClassGraph从@Luke和记黄埔的答案看起来很有趣。答案中还有其他几种可能性。

声明我想要的另一种方式:Animal类中的静态函数查找并实例化了从Animal继承的所有类-无需任何进一步的配置/编码。如果必须进行配置,无论如何,我还是可以在Animal类中实例化它们。我知道这是因为Java程序只是.class文件的松散联合,而事实就是如此。

有趣的是,这似乎在C#中是微不足道的。

关注者
0
被浏览
99
1 个回答
  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    我使用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());
            }
        }
    }
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看