Java 加载文件夹下的所有 class
在 Java 开发中,我们经常会遇到需要动态加载文件夹下的所有 class 的情况。动态加载 class 可以让我们在程序运行时根据需要动态地加载、创建对象和执行方法,极大地提升了程序的灵活性和扩展性。本文将介绍如何使用 Java 的反射机制和类加载器来加载文件夹下的所有 class。
反射机制
Java 的反射机制允许我们在运行时动态地获取类的信息,并调用类的方法、访问类的属性。通过反射机制,我们可以在不知道类名的情况下,根据类名字符串来获取对应的 Class 对象,进而实例化对象和调用方法。
获取 Class 对象
要动态加载文件夹下的所有 class,首先需要获取类的 Class 对象。Java 中有三种方式可以获取 Class 对象。
- 使用
Class.forName()
方法:
Class<?> clazz = Class.forName("com.example.MyClass");
- 使用
.class
语法:
Class<?> clazz = MyClass.class;
- 使用
ClassLoader
的loadClass()
方法:
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
Class<?> clazz = classLoader.loadClass("com.example.MyClass");
实例化对象和调用方法
获取到 Class 对象后,我们就可以通过反射机制实例化对象和调用方法了。
- 实例化对象:
Object obj = clazz.newInstance();
- 调用方法:
Method method = clazz.getMethod("methodName", parameterTypes);
method.invoke(obj, args);
类加载器
类加载器(ClassLoader)是 Java 虚拟机(JVM)用来将字节码加载到内存并转换为 Class 对象的重要组件。Java 中有三种内置的类加载器:Bootstrap ClassLoader、Extension ClassLoader 和 App ClassLoader。
类加载器的层次结构
类加载器之间存在一个父子关系的层次结构。这个层次结构实现了双亲委派模型,即每个类加载器在加载类时会先委托给其父类加载器加载,只有在父类加载器无法找到对应的类时,才会由当前类加载器自己来加载。
下图是类加载器的层次结构示意图:
erDiagram
classLoader <|-- bootstrapClassLoader
classLoader <|-- extensionClassLoader
classLoader <|-- appClassLoader
classLoader <|-- customClassLoader
自定义类加载器
除了使用 Java 内置的类加载器,我们还可以自定义类加载器。自定义类加载器可以用来实现一些特殊的类加载需求,比如从网络、数据库或其他非传统的来源加载类。
自定义类加载器需要继承自 ClassLoader
类,并重写 findClass()
方法来实现类的加载逻辑。
public class CustomClassLoader extends ClassLoader {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
// 自定义加载逻辑
}
}
加载文件夹下的所有 class
现在我们已经了解了反射机制和类加载器的基本原理,下面我们将结合这两个概念,来实现加载文件夹下的所有 class。
public class ClassLoaderUtil {
public static List<Class<?>> loadClassesFromFolder(File folder) throws ClassNotFoundException {
List<Class<?>> classes = new ArrayList<>();
if (folder.isDirectory()) {
File[] files = folder.listFiles();
if (files != null) {
for (File file : files) {
if (file.isFile() && file.getName().endsWith(".class")) {
String className = file.getName().substring(0, file.getName().lastIndexOf("."));
Class<?> clazz = Class.forName(className);
classes.add(clazz);
}
}
}
}
return classes;
}
}
上述代码中,我们定义了一个 ClassLoaderUtil
类,其中的 loadClassesFromFolder()
方法用于加载文件夹下的所有 class。该方法接收一个 File
对象作为参数,遍历文件夹下的所有文件,找到以 .class
结尾的文件,通过反射机制获取对应的 Class 对象,并将其存入一个 List 中返回。
使用示例:
File folder = new File("path