Java动态获取实现某个接口下所有的实现类对象集合

要动态获取实现某个接口下所有的实现类对象集合,需要使用Java的反射机制。具体的流程如下:

  1. 获取实现某个接口的所有类的类名
    可以使用Java的类加载器ClassLoader来获取所有实现类的类名,然后可以通过Class.forName方法获取类对象。在获取类名时,可以设置类加载器的范围,比如只限于当前应用程序的classpath下面,或者包括外部的类库。
List<Class<?>> getImplementClasses(Class<?> interfaceClass) {
    List<Class<?>> list = new ArrayList<>();
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    try {
        for (ClassPath.ClassInfo classInfo : ClassPath.from(classLoader).getTopLevelClasses()) {
            Class<?> clazz = Class.forName(classInfo.getName());
            if (interfaceClass.isAssignableFrom(clazz) && !clazz.isInterface()) {
                list.add(clazz);
            }
        }
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    }
    return list;
}

其中,ClassPath是Google Guava提供的工具包,用于获取类路径下所有类的信息。

  1. 实例化实现类
    对于获取到的每个类,可以使用 newInstance 方法来创建实例。但是由于newInstance方法需要无参构造函数,因此如果实现类没有提供默认构造函数,该方法将会抛出带有 InstantiationExceptionIllegalAccessException 异常的异常。
for (Class<?> clazz : getImplementClasses(MyInterface.class)) {
    try {
        MyInterface obj = (MyInterface) clazz.newInstance();
        // do something with obj
    } catch (InstantiationException | IllegalAccessException e) {
        e.printStackTrace();
    }
}

下面是一个完整的示例,这里假设有一个接口 Shape 和两个实现类 RectangleCircle ,我们需要动态获取这两个实现类的对象集合。

package com.example;

interface Shape {
    void draw();
}

class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing Rectangle");
    }
}

class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing Circle");
    }
}

public class App {
    public static void main(String[] args) {
        for (Class<?> clazz : getImplementClasses(Shape.class)) {
            try {
                Shape shape = (Shape) clazz.newInstance();
                shape.draw();
            } catch (InstantiationException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    private static List<Class<?>> getImplementClasses(Class<?> interfaceClass) {
        List<Class<?>> list = new ArrayList<>();
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        try {
            for (ClassPath.ClassInfo classInfo : ClassPath.from(classLoader).getTopLevelClasses()) {
                Class<?> clazz = Class.forName(classInfo.getName());
                if (interfaceClass.isAssignableFrom(clazz) && !clazz.isInterface()) {
                    list.add(clazz);
                }
            }
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return list;
    }
}

上述代码执行结果为:

Drawing Rectangle
Drawing Circle

这表明,我们成功地动态获取了 Shape 接口下所有的实现类并实例化了它们。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java动态获取实现某个接口下所有的实现类对象集合 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • Java的final修饰符

    final 实例域 可以将实例域定义为 final。对于 final 域来说,构建对象时必须初始化 final 实例域,构造对象之后就不允许改变 final 实例域的值了。也就是说,必须确保在每一个构造器执行之后,final 实例域的值被设置,并且在后面的操作中,不能够再对 final 实例域进行修改。 例如,可以将 Employee 类中的 name 域声…

    Java 2023年4月25日
    00
  • SpringMVC中Json数据格式转换

    下面是详细讲解“SpringMVC中Json数据格式转换”的完整攻略: 什么是SpringMVC中Json数据格式转换? 在SpringMVC中,我们经常需要使用JSON数据格式传输数据,如返回AJAX请求结果等。Json数据格式是一种轻量级的数据交换格式,具有串行化和反串行化的特性,广泛使用在web应用程序的数据传输。 SpringMVC中Json数据格式…

    Java 2023年5月26日
    00
  • 一天吃透SpringMVC面试八股文

    说说你对 SpringMVC 的理解 SpringMVC是一种基于 Java 的实现MVC设计模型的请求驱动类型的轻量级Web框架,属于Spring框架的一个模块。 它通过一套注解,让一个简单的Java类成为处理请求的控制器,而无须实现任何接口。同时它还支持RESTful编程风格的请求。 什么是MVC模式? MVC的全名是Model View Control…

    Java 2023年4月22日
    00
  • Java遍历起止日期中间的所有日期操作

    下面是Java遍历起止日期中间的所有日期的完整攻略: 前置条件 在使用Java进行日期遍历之前,首先需要使用Java提供的LocalDate类来表示起止日期。 LocalDate startDate = LocalDate.of(2021, 5, 1); LocalDate endDate = LocalDate.of(2021, 5, 10); 上面的代码…

    Java 2023年5月20日
    00
  • springBoot使用JdbcTemplate代码实例

    以下是详细的“springBoot使用JdbcTemplate代码实例”的攻略。 一、介绍 JdbcTemplate是Spring框架中的一个类,它提供了访问关系型数据库的方法。使用JdbcTemplate不需要编写复杂的JDBC代码,通过简单的API调用即可实现数据库的操作。 在SpringBoot中,可以通过在pom.xml文件中引入spring-boo…

    Java 2023年5月20日
    00
  • C语言解决青蛙跳台阶问题(升级版)

    我们来讲解一下C语言如何解决青蛙跳台阶问题的升级版。 问题描述 青蛙跳台阶问题是经典的递归问题,其升级版要求在每次跳跃中可以跳1、2、3……n级台阶,问跳上n阶台阶有多少种跳法。 解题思路 在解决青蛙跳台阶问题的升级版时,我们可以将问题转化为数学模型,假设 f(i) 表示跳上第 i 阶台阶需要的跳跃方法数,则有如下公式: f(i)=f(i-1)+f(i-2)…

    Java 2023年5月26日
    00
  • 如何配置类路径?

    以下是关于如何配置类路径的完整使用攻略: 什么是类路径? Java程序在运行时需要加载类文件,而类文件的位置就是通过类路径来指定的。类路径可以包含多个路径,每个路径之间使用分隔符(如冒号或分号)分隔。类路径可以包含目录和JAR文件。 如何配置类路径? 下面介绍三种常见的配置类路径的方法。 方法一:使用命令行参数设置类路径 可以通过命令行参数设置类路径。例如,…

    Java 2023年5月12日
    00
  • 使用BindingResult 自定义错误信息

    下面是关于使用BindingResult自定义错误信息的完整攻略。 一、BindingResult简介 在Spring MVC框架中,接受前端数据的方法一般会使用@ModelAttribute或@RequestBody注解对参数进行声明,此时也可以添加BindingResult类型的参数,用于接收数据绑定时产生的错误信息。 BindingResult是Spr…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部