Java -- 获取指定接口的所有实现类或获取指定类的所有继承类
Class : ClassUtil
package pri.lime.main; import java.io.File; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; /** * 查找指定路径下面实现指定接口的全部类 * * @author Liang * * 2017年5月9日 */ public class ClassUtil { @SuppressWarnings({ "rawtypes", "unchecked" }) public static ArrayList<Class> getAllClassByInterface(Class clazz) { ArrayList<Class> list = new ArrayList<>(); // 判断是否是一个接口 if (clazz.isInterface()) { try { ArrayList<Class> allClass = getAllClass(clazz.getPackage().getName()); /** * 循环判断路径下的所有类是否实现了指定的接口 并且排除接口类自己 */ for (int i = 0; i < allClass.size(); i++) { /** * 判断是不是同一个接口 */ // isAssignableFrom:判定此 Class 对象所表示的类或接口与指定的 Class // 参数所表示的类或接口是否相同,或是否是其超类或超接口 if (clazz.isAssignableFrom(allClass.get(i))) { if (!clazz.equals(allClass.get(i))) { // 自身并不加进去 list.add(allClass.get(i)); } } } } catch (Exception e) { System.out.println("出现异常"); } } else { // 如果不是接口,则获取它的所有子类 try { ArrayList<Class> allClass = getAllClass(clazz.getPackage().getName()); /** * 循环判断路径下的所有类是否继承了指定类 并且排除父类自己 */ for (int i = 0; i < allClass.size(); i++) { if (clazz.isAssignableFrom(allClass.get(i))) { if (!clazz.equals(allClass.get(i))) { // 自身并不加进去 list.add(allClass.get(i)); } } } } catch (Exception e) { System.out.println("出现异常"); } } return list; } /** * 从一个指定路径下查找所有的类 * * @param name */ @SuppressWarnings("rawtypes") private static ArrayList<Class> getAllClass(String packagename) { ArrayList<Class> list = new ArrayList<>(); // 返回对当前正在执行的线程对象的引用。 // 返回该线程的上下文 ClassLoader。 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); String path = packagename.replace('.', '/'); try { ArrayList<File> fileList = new ArrayList<>(); /** * 这里面的路径使用的是相对路径 如果大家在测试的时候获取不到,请理清目前工程所在的路径 使用相对路径更加稳定! * 另外,路径中切不可包含空格、特殊字符等! */ // getResources:查找所有给定名称的资源 // 获取jar包中的实现类:Enumeration<URL> enumeration = // classLoader.getResources(path); Enumeration<URL> enumeration = classLoader.getResources("../bin/" + path); while (enumeration.hasMoreElements()) { URL url = enumeration.nextElement(); // 获取此 URL 的文件名 fileList.add(new File(url.getFile())); } for (int i = 0; i < fileList.size(); i++) { list.addAll(findClass(fileList.get(i), packagename)); } } catch (IOException e) { e.printStackTrace(); } return list; } /** * 如果file是文件夹,则递归调用findClass方法,或者文件夹下的类 如果file本身是类文件,则加入list中进行保存,并返回 * * @param file * @param packagename * @return */ @SuppressWarnings("rawtypes") private static ArrayList<Class> findClass(File file, String packagename) { ArrayList<Class> list = new ArrayList<>(); if (!file.exists()) { return list; } // 返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。 File[] files = file.listFiles(); for (File file2 : files) { if (file2.isDirectory()) { // assert !file2.getName().contains(".");// 添加断言用于判断 if (!file2.getName().contains(".")) { ArrayList<Class> arrayList = findClass(file2, packagename + "." + file2.getName()); list.addAll(arrayList); } } else if (file2.getName().endsWith(".class")) { try { // 保存的类文件不需要后缀.class list.add(Class.forName(packagename + '.' + file2.getName().substring(0, file2.getName().length() - 6))); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } return list; } }
啦啦啦
分类:
JAVA
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决