写了一个工具类,用于获取指定包名下的所有类,支持递归遍历,支持注解过滤,可从 classpath (class 文件与 jar 包)中获取。

import java.io.File;
import java.io.FileFilter;
import java.lang.annotation.Annotation;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;public class ClassUtil {// 获取指定包名下的所有类public static List<Class<?>> getClassList(String packageName, boolean isRecursive) {List<Class<?>> classList = new ArrayList<Class<?>>();try {Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(packageName.replaceAll("\\.", "/"));while (urls.hasMoreElements()) {URL url = urls.nextElement();if (url != null) {String protocol = url.getProtocol();if (protocol.equals("file")) {String packagePath = url.getPath();addClass(classList, packagePath, packageName, isRecursive);} else if (protocol.equals("jar")) {JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();JarFile jarFile = jarURLConnection.getJarFile();Enumeration<JarEntry> jarEntries = jarFile.entries();while (jarEntries.hasMoreElements()) {JarEntry jarEntry = jarEntries.nextElement();String jarEntryName = jarEntry.getName();if (jarEntryName.endsWith(".class")) {String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", ".");if (isRecursive || className.substring(0, className.lastIndexOf(".")).equals(packageName)) {classList.add(Class.forName(className));}}}}}}} catch (Exception e) {e.printStackTrace();}return classList;}// 获取指定包名下的所有类(可根据注解进行过滤)public static List<Class<?>> getClassListByAnnotation(String packageName, Class<? extends Annotation> annotationClass) {List<Class<?>> classList = new ArrayList<Class<?>>();try {Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(packageName.replaceAll("\\.", "/"));while (urls.hasMoreElements()) {URL url = urls.nextElement();if (url != null) {String protocol = url.getProtocol();if (protocol.equals("file")) {String packagePath = url.getPath();addClassByAnnotation(classList, packagePath, packageName, annotationClass);} else if (protocol.equals("jar")) {JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();JarFile jarFile = jarURLConnection.getJarFile();Enumeration<JarEntry> jarEntries = jarFile.entries();while (jarEntries.hasMoreElements()) {JarEntry jarEntry = jarEntries.nextElement();String jarEntryName = jarEntry.getName();if (jarEntryName.endsWith(".class")) {String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", ".");Class<?> cls = Class.forName(className);if (cls.isAnnotationPresent(annotationClass)) {classList.add(cls);}}}}}}} catch (Exception e) {e.printStackTrace();}return classList;}private static void addClass(List<Class<?>> classList, String packagePath, String packageName, boolean isRecursive) {try {File[] files = getClassFiles(packagePath);if (files != null) {for (File file : files) {String fileName = file.getName();if (file.isFile()) {String className = getClassName(packageName, fileName);classList.add(Class.forName(className));} else {if (isRecursive) {String subPackagePath = getSubPackagePath(packagePath, fileName);String subPackageName = getSubPackageName(packageName, fileName);addClass(classList, subPackagePath, subPackageName, isRecursive);}}}}} catch (Exception e) {e.printStackTrace();}}private static File[] getClassFiles(String packagePath) {return new File(packagePath).listFiles(new FileFilter() {@Overridepublic boolean accept(File file) {return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory();}});}private static String getClassName(String packageName, String fileName) {String className = fileName.substring(0, fileName.lastIndexOf("."));if (StringUtil.isNotEmpty(packageName)) {className = packageName + "." + className;}return className;}private static String getSubPackagePath(String packagePath, String filePath) {String subPackagePath = filePath;if (StringUtil.isNotEmpty(packagePath)) {subPackagePath = packagePath + "/" + subPackagePath;}return subPackagePath;}private static String getSubPackageName(String packageName, String filePath) {String subPackageName = filePath;if (StringUtil.isNotEmpty(packageName)) {subPackageName = packageName + "." + subPackageName;}return subPackageName;}private static void addClassByAnnotation(List<Class<?>> classList, String packagePath, String packageName, Class<? extends Annotation> annotationClass) {try {File[] files = getClassFiles(packagePath);if (files != null) {for (File file : files) {String fileName = file.getName();if (file.isFile()) {String className = getClassName(packageName, fileName);Class<?> cls = Class.forName(className);if (cls.isAnnotationPresent(annotationClass)) {classList.add(cls);}} else {String subPackagePath = getSubPackagePath(packagePath, fileName);String subPackageName = getSubPackageName(packageName, fileName);addClassByAnnotation(classList, subPackagePath, subPackageName, annotationClass);}}}} catch (Exception e) {e.printStackTrace();}}
}

获取指定包名下的所有类相关推荐

  1. java 获取包名类名_获取指定包名下的所有类的类名(全名)

    参考来源: 以下代码一键运行: package test; import java.io.File; import java.io.IOException; import java.net.JarUR ...

  2. java 历遍 类_[Java] 遍历指定包名下所有的类(支持jar) | 学步园

    项目需要,仅做记录. 支持包名下的子包名遍历,并使用Annotation(内注)来过滤一些不必要的内部类,提高命中精度. 通过Thread.currentThread().getContextClas ...

  3. [Java] 遍历指定包名下所有的类(支持jar)

    项目需要,仅做记录. 支持包名下的子包名遍历,并使用Annotation(内注)来过滤一些不必要的内部类,提高命中精度. 通过Thread.currentThread().getContextClas ...

  4. 004 关于Java如何扫描指定package下所有的类

    q前言: 在工作中看到这个知识点,就顺便参考了百度的一些资料,整理一下,希望以后用的到. 一:理论部分 1.使用场景 写一个MVC框架,需要从包中扫描出组件并注册到容器中,而JDK没有提供现成的从方法 ...

  5. 获取Java接口的所有实现类

    获取Java接口的所有实现类 前言:想看基于spring 的最简单实现方法,请直接看 第七步. 本文价值在于 包扫描的原理探究和实现 一.背景 项目开发中,使用Netty做服务端,保持长连接与客户端( ...

  6. Spring Boot 自动加载指定包下的拦截器

    Spring Boot 在我们需要对程序添加拦截器需要使用 WebMvcConfigurerAdapter 中的 addInterceptors方法去注册拦截器,这样我们如果在程序里面有多个拦截或者我 ...

  7. java扫描包下类_实现获取扫描指定包路径下的jar文件或class文件JarPojoHandler类示例代码...

    通过JarPojoHandler类实现了扫描指定路径下如何获取所有的JAR包或class文件,可以对特定class对象文件筛选过滤等,具体代码如下所示import java.io.File;@b@im ...

  8. java 扫描类_Java扫描指定包中所有类

    1. 扫描类 import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.n ...

  9. java反射获取包下所有的类

    引三方包 <dependency><groupId>org.reflections</groupId><artifactId>reflections&l ...

最新文章

  1. 每一种创伤,都是一种成熟
  2. oracle中decode和case的使用例子
  3. 浅谈:MyBatis-Plus的CRUD与乐观锁,分页插件,逻辑删除
  4. CCNA试验-1标准acl
  5. 函数调用 压栈的工作原理
  6. Windows获取CPU、内存和磁盘使用率脚本
  7. 算法题 如何找到数组中重复的数字
  8. 很经典的独白,搞网络的童鞋们,你们懂得
  9. 我是如何晋升专家岗的
  10. java,mysql,hadoop,cdh,hive,spark,ntp,zookeeper,kafka,storm,redis,flume,git 安装详解
  11. C++复习笔记3——类与对象(赋值重载、临时对象、const、static)
  12. android app套壳马甲开发,Android应用开发最佳实践:马甲包配置管理
  13. 《软技能:代码之外的生存指南》读书笔记
  14. 年薪40W的程序员,需要有哪些技能傍身?
  15. Strings, bytes, runes and characters in Go
  16. 【webGoat】Broken Access Control
  17. blender 学习
  18. Visual Haze Removal by a Unified GenerativeAdversarial Network(基于生成式对抗网络的图像去雾IEEE2019)
  19. 怎样在ZBrush中快速绘制人体躯干
  20. 离人工智能进入我们的社会还有多远?(CES 2022 新品尝鲜)

热门文章

  1. ACE中静态实例管理方式
  2. 编译器会影响编译吗?
  3. 贪心+构造 Codeforces Round #277 (Div. 2) C. Palindrome Transformation
  4. 查看是否安装android sdk
  5. 11.14PMP试题每日一题
  6. 将VMware Workstation 12 Pro的虚拟网卡修改为自己希望的IP网段
  7. Wi-Fi与LTE走向融合,优势互补携手共赢
  8. 瑞士电信vCPE商用落地 华三通信NFV方案成最大功臣
  9. 创维37K05HR黑屏有声音故障维修
  10. ENode 2.0 - 深入分析ENode的内部实现流程和关键地方的幂等设计