At runtime, find all classes in a Java application that extend a base class

技术标签: 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() );

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

With the above approach, I can simply create a new class that extends Animal and it'll get picked up automatically.

UPDATE: 10/16/2008 9:00 a.m. Pacific Standard Time:

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 回答 org.reflections 看起来不错。还 ClassGraph from @Luke Hutchison's 回答 looks interesting. There are several more possibilities in the answers as well.

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.

Interestingly, it seems this is fairly trivial 在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());
        }
    }
}

智能推荐

A Glance at Web Application Security

Applies To The Information provided in this article applies to the following technologies: Windows Server 2003 family OS, IIS 6.0, .Net Framework 2.0 & Asp.Net 2.0 Introduction Web application sec...

STM32cubeMX打开错误 the application requires a java runtime environment 1.7.0

打开软件出现以上错误。 解决方法: 打开STM32cubeMX.exe所在的安装文件夹, 按住Shift键,在文件夹空白处点击鼠标右键,点击“在此处打开PowerShell窗口”, 然后输入   java -jar 要打开的文件名(包括后缀名)  ,然后回车即可打开文件,该方法同样适用打开.jar和一些其他的文件。...

运行FreeMind 弹出This application requires a Java Runtime Environment 1.5.0解决办法

系统已经安装过了java1.8(解压缩版的),已经安装了 jdk ,并且设置好了 java 环境变量,CMD 运行 java 或 javac 都正常,其他依赖 jdk 的应用程序都能正常运行,安装完FreeMind提示需要java1.5.0环境 解决方法如下: 1:点击上图中提示的确定按钮,浏览器自动跳转到下图,接着根据提示安装java环境; 2.安装成功后,双击桌面FreeMind图标就能成功运...

This application requires a Java Runtime Environment 1.7.0 或 1.8.0 (64-bit)

运行 jadx-gui-0.9.0.exe 应用程序时报: This application requires a Java Runtime Environment 1.8.0 (64-bit) 不同的 jadx-gui.exe 提示的信息可能不同,低版本的可能是: This application requires a Java Runtime Environment 1.7.0 找不到jre环...

Eclipse:Cannot find System Java Compiler. Ensure that you have installed a JDK (not just a JRE)

Eclipse编辑器Gradle(STS)编译代码,报错的问题 使用Gradle(STS)build报错:java.lang.RuntimeException: Cannot find System Java Compiler. Ensure that you have install a JDK not a JRE 首先排查eclipse是否已经导入相应的jre 查看方法:Window----&...

猜你喜欢

Eclipse:Cannot find System Java Compiler. Ensure that you have installed a JDK (not just a JRE)

eclipse在启动的时候需要设置默认的jdk地址,即javaw.exe文件的地址,该地址和eclipse的编译jdk路径需要一致,如果没有加上的话需要加上(特别是在用构建工具如gradle的时候,没用过maven和ant,不知道是不是也受这个影响) 解决的主要步骤:编辑eclipse目录下的eclipse.ini,该文件是eclipse的初始化文件,需要在文件开头加上 -vm C:\Progra...

解决:Cannot find System Java Compiler. Ensure that you have installed a JDK (not just a JRE)

导入github上的项目,有时候,就会报如下的错误 Error:Execution failed for task ':app:compileDebugJava'. > Cannot find System Java Compiler. Ensure that you have installed a JDK (not just a JRE) and configured your JAVA...

redis中的hash扩容渐进式rehash过程

背景: redis字典(hash表)当数据越来越多的时候,就会发生扩容,也就是rehash 对比:java中的hashmap,当数据数量达到阈值的时候(0.75),就会发生rehash,hash表长度变为原来的二倍,将原hash表数据全部重新计算hash地址,重新分配位置,达到rehash目的 redis中的hash表采用的是渐进式hash的方式: 1、redis字典(hash表)底层有...

不同系统下的回车\r和换行\n,及其历史

2019独角兽企业重金招聘Python工程师标准>>>      我们平时按下键盘上的‘回车键’,就能实现回车换行【我们在屏幕上所看到的就是光标移到了下一行的开头位置!!ps:不讨论软件实现的特殊功能,如word里的回车智能缩进】。因此对这个按键更准确说应该叫做‘回车换行键’ 就且将这种将光标移到下行开...

windows操作系统,python环境下django的自动安装

首先,在Windows操作系统下安装python,完成python环境的搭建。(我看有的博客需要配置环境变量,其实不必要,因为我们在安装的时候只要勾选如下图所示即可避免不必要的麻烦) 第二步,使用快捷键windows+R或者点击如下图所示,之后点击运行 在其中输入cmd即可进入dos命令。 第三步,输入以下命令 就会自动安装,等待安装完成即可。 第四步,检测django是否安装成功,如果出现如下图...

问答精选

How to get the sum of rows using a vector and the make the result in a column

I have a dataframe and i want to calculate the sum of variables present in a vector in every row and make the sum in other variable after i want the name of new variable created to be from the name of...

Call a custom class in zend framework

I have a very rough project that done partially in zend framework (not ZF2). The 'application', 'library' and 'public' folders are on the same root. Now i need to create a library 'Anil' in the 'libra...

Hide Some Of The Categories In Magento?

I want to hide some of the categories from magento home page. I have created some categories like New Arrivals, Special Offer Which I would like to show in some different way may be in left panel or r...

Reading an internal file in Android Studio

I am writing to an internal file in Android Studio The code lets me write lines of data split with commas. I am able to then go to another activity and read it all out at once. However I want to be ab...

Rails Acts_as_votable Gem Like/Unlike Buttons with Ajax

I'm new to Ruby On Rails, I used the acts_as_votable gem to create Like and Unlike Buttons to make Users like and unlike Posts but I can't make them change from Like to Unlike (and viceversa) and upda...

相关问题

相关文章

热门文章

推荐文章

相关标签

推荐问答