其实我的需求是在系统中 测试用户导入的jar包,所有网上找了很多解决方案,踩过很多坑,再加上以前搞c++的,对java不是很熟,
这里特意记录下,算是基本满足需求了

使用反射获得jar包中的类、方法、参数、返回值类型

使用反射获取jar包中的类、方法、参数、以及返回类型,主要参照这篇文章
https://blog.csdn.net/chen7019/article/details/105708338

这里面我的TestJar.jar 里面 就一个Demo类,是这样的:

package com.baidu;public class Demo {public Demo() {}public static void main(String[] args) {}public String getInfo() {return "hello world";}public int getSum(int a, int b) {return a + b;}
}
    @Testpublic void test2() {String path = "E:\\Desktop\\Programmer\\JavaFile\\MyWeb\\test\\web\\WEB-INF\\lib\\";String fileName = "TestJar.jar";try {JarFile jarFile = new JarFile(path + fileName);Enumeration<JarEntry> e = jarFile.entries();JarEntry entry;while (e.hasMoreElements()) {entry = (JarEntry) e.nextElement();//if (entry.getName().indexOf("META-INF") < 0 && entry.getName().indexOf(".class") >= 0) {String classFullName = entry.getName();//去掉后缀.classString className = classFullName.substring(0, classFullName.length() - 6).replace("/", ".");System.out.println(className);Class<?> c = null;try {try {// 用className这个类来装载c,但还没有实例化c = Class.forName(className);} catch (ClassNotFoundException e1) {e1.printStackTrace();}Method[] methods = c.getMethods();for (Method method : methods) {String methodName = method.getName();System.out.println("方法名称:" + methodName);System.out.println("返回值类型" + method.getReturnType());Class<?>[] parameterTypes = method.getParameterTypes();for (Class<?> clas : parameterTypes) {// String parameterName = clas.getName();String parameterName = clas.getSimpleName();System.out.println("参数类型:" + parameterName);}System.out.println("==========================");}} catch (Exception e1) {}}}} catch (IOException e) {e.printStackTrace();}}

运行代码后的输出结果

com.baidu.Demo
方法名称:main
返回值类型void
参数类型:String[]
==========================
方法名称:getSum
返回值类型int
参数类型:int
参数类型:int
==========================
方法名称:getInfo
返回值类型class java.lang.String
==========================
方法名称:wait
返回值类型void
参数类型:long
参数类型:int
==========================
方法名称:wait
返回值类型void
==========================
方法名称:wait
返回值类型void
参数类型:long
==========================
方法名称:equals
返回值类型boolean
参数类型:Object
==========================
方法名称:toString
返回值类型class java.lang.String
==========================
方法名称:hashCode
返回值类型int
==========================
方法名称:getClass
返回值类型class java.lang.Class
==========================
方法名称:notify
返回值类型void
==========================
方法名称:notifyAll
返回值类型void
==========================Process finished with exit code 0

如何动态实例化一个类,并运行其中的方法

//用className来状态这个c,className就是上面那个代码中的,可以理解为com.xxx.xxx(去掉了后面的.class)
Class<?> c = null;
c = Class.forName(className);
//创建对象实例
Object instance=c.newInstance();

这样还不能直接调用instance的方法,要先获取 这个类中的方法 然后再 invoke;
这里我以 TestJar.jar 里面的demo 类下的 getInfo 方法为例:

// 用className这个类来装载c
c = Class.forName(className);
// 实例化对象
Object instance=c.newInstance();
//获取实例当中的方法名为show,参数只有一个且类型为string的public方法
Method method=c.getMethod("getInfo");
// 如果该方法有参数,后面就跟参数类型
// Method method = MyTest.getMethod("show", String.class);//  //传入实例以及方法参数信息(如果有)执行这个方法
Object ret = method.invoke(instance);System.out.println("运行动态装载jar包的getInfo方法,并获得输出");
// 如果有返回值,可以直接打印ret获得输出
System.out.println(method.invoke(instance ));

全部代码

    public void test2() {String path = "E:\\Desktop\\Programmer\\JavaFile\\MyWeb\\test\\web\\WEB-INF\\lib\\";String fileName = "TestJar.jar";try {JarFile jarFile = new JarFile(path + fileName);Enumeration<JarEntry> e = jarFile.entries();JarEntry entry;while (e.hasMoreElements()) {entry = (JarEntry) e.nextElement();//if (entry.getName().indexOf("META-INF") < 0 && entry.getName().indexOf(".class") >= 0) {String classFullName = entry.getName();//去掉后缀.classString className = classFullName.substring(0, classFullName.length() - 6).replace("/", ".");System.out.println(className);Class<?> c = null;try {try {// 用className这个类来装载cc = Class.forName(className);Object instance=c.newInstance();Method method=c.getMethod("getInfo");System.out.println("运行动态装载jar包的getInfo方法,并获得输出");System.out.println(method.invoke(instance ));} catch (ClassNotFoundException e1) {e1.printStackTrace();}Method[] methods = c.getMethods();for (Method method : methods) {String methodName = method.getName();System.out.println("方法名称:" + methodName);System.out.println("返回值类型" + method.getReturnType());Class<?>[] parameterTypes = method.getParameterTypes();for (Class<?> clas : parameterTypes) {// String parameterName = clas.getName();String parameterName = clas.getSimpleName();System.out.println("参数类型:" + parameterName);}System.out.println("==========================");}} catch (Exception e1) {}}}} catch (IOException e) {e.printStackTrace();}}

输出

com.baidu.Demo
运行动态装载jar包的getInfo方法,并获得输出
hello world
方法名称:main
返回值类型void
参数类型:String[]
==========================
方法名称:getSum
返回值类型int
参数类型:int
参数类型:int
==========================
方法名称:getInfo
返回值类型class java.lang.String
==========================
方法名称:wait
返回值类型void
参数类型:long
参数类型:int
==========================
方法名称:wait
返回值类型void
==========================
方法名称:wait
返回值类型void
参数类型:long
==========================
方法名称:equals
返回值类型boolean
参数类型:Object
==========================
方法名称:toString
返回值类型class java.lang.String
==========================
方法名称:hashCode
返回值类型int
==========================
方法名称:getClass
返回值类型class java.lang.Class
==========================
方法名称:notify
返回值类型void
==========================
方法名称:notifyAll
返回值类型void
==========================Process finished with exit code 0

用getSum方法也是一样:

c = Class.forName(className);
Object instance=c.newInstance();
Method method=c.getMethod("getSum",int.class,int.class);
System.out.println("运行动态装载jar包的getSum方法,并获得输出");
System.out.println(method.invoke(instance,2,3));
com.baidu.Demo
运行动态装载jar包的getSum方法,并获得输出
5

使用反射获得jar包中的类、方法、参数、返回值类型,然后动态加载jar包运行方法相关推荐

  1. java动态加载jar文件并执行方法

    在项目开发的过程中,有时候需要动态灵活的加载某个jar包并执行里面的方法的时候,我们可以使用本篇文章写得方式去动态的加载jar包而不用使用原始方式引入jar包作为lib去使用,接下来介绍如何动态加载j ...

  2. flink sql udf jar包_Java动态加载Jar实例解析

    导读:在实际项目开发中,有时会遇到需动态加载jar包的应用场景.如将Flink的UDF自定义方法制作成方法库(既打成一个Jar),在提交给Flink集群的Job中动态加载jar便可使用.下面将举一个简 ...

  3. java动态加载jar时,jar中还有第三方jar无法加载的解决方法

    java动态加载jar时,jar中还有第三方jar无法加载的解决方法 当java插件化开发时,即一个java程序在运行的情况下动态加载另一个jar,网上大多数的方法如下 public static v ...

  4. android动态jar,Android动态加载Jar(包含第三方依赖Jar)

    最近项目有一个需求,需要根据用户需求动态加载APP内某功能模块,且当该部分功能模块代码有变动,只需更新该功能JAR,无需更新整个APK,基于这个需求,决定采用动态加载Jar的方式去实现,于是各种查资料 ...

  5. Java中动态加载字节码的方法 (持续补充)

    文章目录 Java中动态加载字节码的方法 1.利用 URLClassLoader 加载远程class文件 2.利用 ClassLoader#defineClass 直接加载字节码 2.1 类加载 - ...

  6. [转]Android动态加载jar/dex

    本文转自:http://www.cnblogs.com/over140/archive/2011/11/23/2259367.html 前言 在目前的软硬件环境下,Native App与Web App ...

  7. Java动态加载jar及class文件

    经常碰到需要动态加载jar及class文件的场景.Java类由于需要加载和编译字节码,动态加载class文件较为麻烦,但JDK仍提供了一整套方法来动态加载jar文件和class文件. 一.动态加载ja ...

  8. Spring实战之Spring动态加载jar模块和卸载模块

    加载 Spring提供了下面这些类来加载外部jar. classPathResorce可以用来加载类路径上的jar. 一般推荐使用 classLoader = new UrlClassLoader(n ...

  9. java动态打jar包_java动态加载jar包

    目录结构如下. ├── main │   ├── java │   │   └── lu │   │   └── tool │   │   └── jar │   │   ├── InterfaceR ...

最新文章

  1. centos8网络配置开启wifi_CentOS 7.5 最小安装开启 WIFI 连接的设置方法
  2. mysql 如何凭借几个列_我如何总结MySQL中的几个列
  3. 50: Luogu P4568 分层图
  4. 【C语言】第六章 集合数据与数组 题解
  5. 使Ruby自动定位查找本地路径
  6. Electron的学习笔记
  7. pod trunk push --verbose 失败的原因总结
  8. 如何在自己的网站中嵌入其他网站的页面?
  9. 新学期flag-适合每个人的专业课
  10. 无线宽带接入802.16技术简介(转)
  11. 未明学院数据分析报告:漫威之父斯坦· 李走了,大数据分析他的“漫威宇宙”
  12. c 添加mysql表单的一行数据类型,MySQL InnoDB表行格式及压缩
  13. STM32F4基于DMA的多通道ADC采集——遇到的问题解决
  14. Python之心算练习程序
  15. javascript中用三元运算符实现手动图片转换
  16. htslib和Samtool安装步骤
  17. repo remote元素中fetch=“.“或者“..“的理解
  18. 【日常分享】知道手机号,如何查姓名?
  19. uniapp 购物车页面解决实时刷新的问题
  20. 宏基因组有参分析和无参分析差异

热门文章

  1. c#进阶之lambda表达式
  2. Aho-Corasick算法
  3. iOS通过切片仿断点机制上传文件
  4. 20145201 20145227 《信息安全系统设计基础》实验二 固件开发
  5. 命运(HDU 2571 简单动态规划)
  6. iOS开发实用技术之推送-应用间跳转-社交分享
  7. shiro 与spring的集成
  8. Eclipse自动生成方法注释 快捷键
  9. [转]Spring注解-@Configuration注解、@Bean注解以及配置自动扫描、bean作用域
  10. Android深度探索第五章总结