如何获取指定java包中的所有类
正文
项目里有时候需要获取某个包下面的所有类。这些类可能需要做代理,可能需要获取这些类的注解用于其他处理。
解决方法
1.获取类加载器 ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
2.通过类加载器获取资源 Enumeration<URL> resources = classLoader.getResources(path);
3.Enumeration
该接口有两个方法 hasMoreElements() 和 nextElement()。
这个接口已被迭代器取代,可能是为了兼容,所以还保留着。
4.遍历所有资源
while (resources.hasMoreElements()) {
URL url = resources.nextElement();
File file = new File(url.getFile());
//.... 获取所有文件
}
完整代码
package org.example;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
/**
* @author zhb
*/
public class EmptyMain {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//获取当前类加载器
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
//需要查找的包名
String packageName = "org.example";
String path = packageName.replace('.', '/');
//通过类加载器查找资源
Enumeration<URL> resources = classLoader.getResources(path);
//获取的类名列表
List<String> fs = new ArrayList<>();
while (resources.hasMoreElements()) {
URL url = resources.nextElement();
File file = new File(url.getFile());
//这里传上级包名
listAllClasses(file, fs, "org");
}
fs.forEach(f -> {
try {
//获取类Class
Class<?> aClass = classLoader.loadClass(f);
Test annotation = aClass.getAnnotation(Test.class);
if (annotation != null) {
System.out.println(aClass);
System.out.println(f);
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
});
}
public static void listAllClasses(File file, List<String> list, String pkg) {
if (file.isDirectory()) {
File[] files = file.listFiles();
if (files == null) {
return;
}
pkg += "." + file.getName();
for (File tempFile : files) {
//递归调用
listAllClasses(tempFile, list, pkg);
}
} else {
list.add(pkg + "." + file.getName().substring(0, file.getName().length() - 6));
}
}
}