要动态获取实现某个接口下所有的实现类对象集合,需要使用Java的反射机制。具体的流程如下:
- 获取实现某个接口的所有类的类名
可以使用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提供的工具包,用于获取类路径下所有类的信息。
- 实例化实现类
对于获取到的每个类,可以使用newInstance
方法来创建实例。但是由于newInstance方法需要无参构造函数,因此如果实现类没有提供默认构造函数,该方法将会抛出带有InstantiationException
或IllegalAccessException
异常的异常。
for (Class<?> clazz : getImplementClasses(MyInterface.class)) {
try {
MyInterface obj = (MyInterface) clazz.newInstance();
// do something with obj
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
下面是一个完整的示例,这里假设有一个接口 Shape
和两个实现类 Rectangle
和 Circle
,我们需要动态获取这两个实现类的对象集合。
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技术站