使用反射获得jar包中的类、方法、参数、返回值类型,然后动态加载jar包运行方法
其实我的需求是在系统中 测试用户导入的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包运行方法相关推荐
- java动态加载jar文件并执行方法
在项目开发的过程中,有时候需要动态灵活的加载某个jar包并执行里面的方法的时候,我们可以使用本篇文章写得方式去动态的加载jar包而不用使用原始方式引入jar包作为lib去使用,接下来介绍如何动态加载j ...
- flink sql udf jar包_Java动态加载Jar实例解析
导读:在实际项目开发中,有时会遇到需动态加载jar包的应用场景.如将Flink的UDF自定义方法制作成方法库(既打成一个Jar),在提交给Flink集群的Job中动态加载jar便可使用.下面将举一个简 ...
- java动态加载jar时,jar中还有第三方jar无法加载的解决方法
java动态加载jar时,jar中还有第三方jar无法加载的解决方法 当java插件化开发时,即一个java程序在运行的情况下动态加载另一个jar,网上大多数的方法如下 public static v ...
- android动态jar,Android动态加载Jar(包含第三方依赖Jar)
最近项目有一个需求,需要根据用户需求动态加载APP内某功能模块,且当该部分功能模块代码有变动,只需更新该功能JAR,无需更新整个APK,基于这个需求,决定采用动态加载Jar的方式去实现,于是各种查资料 ...
- Java中动态加载字节码的方法 (持续补充)
文章目录 Java中动态加载字节码的方法 1.利用 URLClassLoader 加载远程class文件 2.利用 ClassLoader#defineClass 直接加载字节码 2.1 类加载 - ...
- [转]Android动态加载jar/dex
本文转自:http://www.cnblogs.com/over140/archive/2011/11/23/2259367.html 前言 在目前的软硬件环境下,Native App与Web App ...
- Java动态加载jar及class文件
经常碰到需要动态加载jar及class文件的场景.Java类由于需要加载和编译字节码,动态加载class文件较为麻烦,但JDK仍提供了一整套方法来动态加载jar文件和class文件. 一.动态加载ja ...
- Spring实战之Spring动态加载jar模块和卸载模块
加载 Spring提供了下面这些类来加载外部jar. classPathResorce可以用来加载类路径上的jar. 一般推荐使用 classLoader = new UrlClassLoader(n ...
- java动态打jar包_java动态加载jar包
目录结构如下. ├── main │ ├── java │ │ └── lu │ │ └── tool │ │ └── jar │ │ ├── InterfaceR ...
最新文章
- centos8网络配置开启wifi_CentOS 7.5 最小安装开启 WIFI 连接的设置方法
- mysql 如何凭借几个列_我如何总结MySQL中的几个列
- 50: Luogu P4568 分层图
- 【C语言】第六章 集合数据与数组 题解
- 使Ruby自动定位查找本地路径
- Electron的学习笔记
- pod trunk push --verbose 失败的原因总结
- 如何在自己的网站中嵌入其他网站的页面?
- 新学期flag-适合每个人的专业课
- 无线宽带接入802.16技术简介(转)
- 未明学院数据分析报告:漫威之父斯坦· 李走了,大数据分析他的“漫威宇宙”
- c 添加mysql表单的一行数据类型,MySQL InnoDB表行格式及压缩
- STM32F4基于DMA的多通道ADC采集——遇到的问题解决
- Python之心算练习程序
- javascript中用三元运算符实现手动图片转换
- htslib和Samtool安装步骤
- repo remote元素中fetch=“.“或者“..“的理解
- 【日常分享】知道手机号,如何查姓名?
- uniapp 购物车页面解决实时刷新的问题
- 宏基因组有参分析和无参分析差异