当前位置: 首页 > news >正文

获取class java_Java获取package下所有的class对象(普通文件包和Jar文件包)

读取一个package路径下面所有的class。

起初觉得很简单,只需要通过IO流找到文件,然后取出下面的所有文件,然后通过反射得到Class对象。

但是发现从普通文件包下面这样做很容易,但是要是package在一个jar文件的下,这就比价麻烦了,因为我们不能通过文件对象File那样直接定位到jar文件下面的内容。所以我们需要使用特殊的方式。

第一种:普通文件安包中的package里面

/**

* 获得包下面的所有的class

*

* @param pack

* package完整名称

* @return List包含所有class的实例

*/

public static List getClasssFromPackage(String pack) {

List clazzs = new ArrayList();

// 是否循环搜索子包

boolean recursive = true;

// 包名字

String packageName = pack;

// 包名对应的路径名称

String packageDirName = packageName.replace('.', '/');

Enumeration dirs;

try {

dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);

while (dirs.hasMoreElements()) {

URL url = dirs.nextElement();

String protocol = url.getProtocol();

if ("file".equals(protocol)) {

System.out.println("file类型的扫描");

String filePath = URLDecoder.decode(url.getFile(), "UTF-8");

findClassInPackageByFile(packageName, filePath, recursive, clazzs);

} else if ("jar".equals(protocol)) {

System.out.println("jar类型的扫描");

}

}

} catch (Exception e) {

e.printStackTrace();

}

return clazzs;

}

/**

* 在package对应的路径下找到所有的class

*

* @param packageName

* package名称

* @param filePath

* package对应的路径

* @param recursive

* 是否查找子package

* @param clazzs

* 找到class以后存放的集合

*/

public static void findClassInPackageByFile(String packageName, String filePath, final boolean recursive, List clazzs) {

File dir = new File(filePath);

if (!dir.exists() || !dir.isDirectory()) {

return;

}

// 在给定的目录下找到所有的文件,并且进行条件过滤

File[] dirFiles = dir.listFiles(new FileFilter() {

@Override

public boolean accept(File file) {

boolean acceptDir = recursive && file.isDirectory();// 接受dir目录

boolean acceptClass = file.getName().endsWith("class");// 接受class文件

return acceptDir || acceptClass;

}

});

for (File file : dirFiles) {

if (file.isDirectory()) {

findClassInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive, clazzs);

} else {

String className = file.getName().substring(0, file.getName().length() - 6);

try {

clazzs.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + "." + className));

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

第二种:获取jar文件包中的package下面的所有class

/**

* 从jar文件中读取指定目录下面的所有的class文件

*

* @param jarPaht

* jar文件存放的位置

* @param filePaht

* 指定的文件目录

* @return 所有的的class的对象

*/

public List getClasssFromJarFile(String jarPaht, String filePaht) {

List clazzs = new ArrayList();

JarFile jarFile = null;

try {

jarFile = new JarFile(jarPaht);

} catch (IOException e1) {

e1.printStackTrace();

}

List jarEntryList = new ArrayList();

Enumeration ee = jarFile.entries();

while (ee.hasMoreElements()) {

JarEntry entry = (JarEntry) ee.nextElement();

// 过滤我们出满足我们需求的东西

if (entry.getName().startsWith(filePaht) && entry.getName().endsWith(".class")) {

jarEntryList.add(entry);

}

}

for (JarEntry entry : jarEntryList) {

String className = entry.getName().replace('/', '.');

className = className.substring(0, className.length() - 6);

try {

clazzs.add(Thread.currentThread().getContextClassLoader().loadClass(className));

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

return clazzs;

此外,我们可以通过JarEntry对象,将jar文件中的一个文件以流的方式输出来

/**

* 通过流将jar中的一个文件的内容输出

*

* @param jarPaht

* jar文件存放的位置

* @param filePaht

* 指定的文件目录

*/

public static void getStream(String jarPaht, String filePaht) {

JarFile jarFile = null;

try {

jarFile = new JarFile(jarPaht);

} catch (IOException e1) {

e1.printStackTrace();

}

Enumeration ee = jarFile.entries();

List jarEntryList = new ArrayList();

while (ee.hasMoreElements()) {

JarEntry entry = (JarEntry) ee.nextElement();

// 过滤我们出满足我们需求的东西,这里的fileName是指向一个具体的文件的对象的完整包路径,比如com/mypackage/test.txt

if (entry.getName().startsWith(filePaht)) {

jarEntryList.add(entry);

}

}

try {

InputStream in = jarFile.getInputStream(jarEntryList.get(0));

BufferedReader br = new BufferedReader(new InputStreamReader(in));

String s = "";

while ((s = br.readLine()) != null) {

System.out.println(s);

}

} catch (IOException e) {

e.printStackTrace();

}

}

测试上面的所有内容

public static void main(String[] args) {

ClassUtil classUtil = new ClassUtil();

List clazzs = classUtil.getClasssFromPackage("包名");//

for (Class clazz : clazzs) {

System.out.println(clazz.getName());

}

clazzs = classUtil.getClasssFromJarFile("Jar文件的路径", "Jar文件里面的包路径");

for (Class clazz : clazzs) {

System.out.println(clazz.getName());

}

classUtil.getStream("Jar文件的路径", "Jar文件总的一个具体文件的路径");

}

相关文章:

  • 解密海底捞模式:难以复制的简单
  • byte 转string java_转:Java中String与byte[]的转换
  • SD 2.0会前花絮:让我们互相签售吧
  • 基于法线的边缘检测
  • java线程之间通信方式_Java线程与线程、进程与进程之间通信方式
  • eclipse技巧学习
  • java中的计数器_Simple Java—Collections(一)Java高效计数器
  • 关注Blender-开源的3D创作软件
  • selenium excel java_Java自动化——使用Selenium+POI实现Excel自动化批量查单词
  • mysql or拼接_MySQL 中 and 和 or 的组合使用
  • python操作文件和目录_python-操作文件和目录
  • python每日练习题_Python经典基础编程练习题(四)——每日10题
  • 梦到深处梦须断——《梦断代码》是本什么书?
  • dbconn Java_关于java jdbc 数据连接类(dbconnection)
  • java 1000转_Java中如何把 ¥1001 转换表示为 一千零一
  • axios 和 cookie 的那些事
  • CentOS7 安装JDK
  • Java程序员幽默爆笑锦集
  • Mac转Windows的拯救指南
  • React16时代,该用什么姿势写 React ?
  • Vue.js-Day01
  • Vue实战(四)登录/注册页的实现
  • XML已死 ?
  • 测试开发系类之接口自动化测试
  • 让你的分享飞起来——极光推出社会化分享组件
  • 软件开发学习的5大技巧,你知道吗?
  • 应用生命周期终极 DevOps 工具包
  • 正则学习笔记
  • kubernetes资源对象--ingress
  • 微龛半导体获数千万Pre-A轮融资,投资方为国中创投 ...
  • ​ ​Redis(五)主从复制:主从模式介绍、配置、拓扑(一主一从结构、一主多从结构、树形主从结构)、原理(复制过程、​​​​​​​数据同步psync)、总结
  • #13 yum、编译安装与sed命令的使用
  • #Java第九次作业--输入输出流和文件操作
  • #预处理和函数的对比以及条件编译
  • $ git push -u origin master 推送到远程库出错
  • $().each和$.each的区别
  • $forceUpdate()函数
  • (42)STM32——LCD显示屏实验笔记
  • (安卓)跳转应用市场APP详情页的方式
  • (二十一)devops持续集成开发——使用jenkins的Docker Pipeline插件完成docker项目的pipeline流水线发布
  • (二刷)代码随想录第16天|104.二叉树的最大深度 559.n叉树的最大深度● 111.二叉树的最小深度● 222.完全二叉树的节点个数
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (算法)Game
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • .Net CF下精确的计时器
  • .net core webapi 部署iis_一键部署VS插件:让.NET开发者更幸福
  • .net framework 4.0中如何 输出 form 的name属性。
  • .NET MVC 验证码
  • .NET命令行(CLI)常用命令
  • .net专家(高海东的专栏)
  • /ThinkPHP/Library/Think/Storage/Driver/File.class.php  LINE: 48
  • @reference注解_Dubbo配置参考手册之dubbo:reference