Java加载jar文件并调用jar文件当中有参数和返回值的方法

在工作当中经常遇到反编译后的jar文件,并要传入参数了解其中的某些方法的输出,想到Java里面的反射可以实现加载jar文件并调用其中的方法来达到自己的目的。就写了个Demo代码。

以下的类可以编译生成hello.jar文件。

 1 package org.lele.fatpanda;
 2
 3 public class Util
 4 {
 5     public static String myName;
 6     /*
 7      * 无参数,无返回值的方法。
 8      */
 9     public static void getVersion()
10     {
11         System.out.println("java version: " + System.getProperty("java.version") );
12     }
13     /*
14      *有参数,无返回值的方法。
15      */
16     public static void setTmpName(String name)
17     {
18         myName = name;
19         System.out.println("Set Tmp Name Succeed and the name is : " + myName);
20     }
21     /*
22      * 单个参数,有返回值的方法。
23      */
24     public static String getName(String prefix)
25     {
26         return prefix + "lele";
27     }
28     /*
29      * 多个参数,有返回值的方法。
30      */
31     public static String test(String i1, int i2)
32     {
33         return i1 + i2;
34     }
35
36 }
37 /*
38  * 一个生成jar文件的类文件,要使用public的访问权限,如果在方便进行反射调用,则要将方法声明为static。
39  */  

下面的就是实现动态加载并调用的主要代码。

 1 package com.xiyoulele.wh;
 2
 3 import java.io.File;
 4 import java.lang.reflect.Method;
 5 import java.net.URL;
 6 import java.net.URLClassLoader;
 7
 8 public class Main
 9 {
10     public static void main(String[] args)
11     {
12         URL[] urls = new URL[] {};
13         MyClassLoader classLoader = new MyClassLoader(urls, null);  //自定义ClassLoader来加载jar文件
14
15         try
16         {
17             classLoader.addJar(new File("c:\\hello.jar").toURI().toURL());  //加载特定路径的jar文件
18             Class<?> clazz = classLoader.loadClass("org.lele.fatpanda.Util"); //动态加载jar文件当中的特定类的class文件
19
20             //传入一个参数一个返回值
21
22             Class<?>[] typeA = new Class[1];  //传入要调用的方法的参数类型
23             typeA[0] = String.class;
24
25             Object[] objsA = new Object[1];  //传入要调用的方法的具体参数
26             objsA[0] = new String("xiyou");
27
28             Method method =  clazz.getDeclaredMethod("getName", typeA);  //获取要被调用的特定方法  getName(String xx)
29
30             String result = method.invoke(clazz, objsA).toString(); //调用方法,获取方法的返回值。
31
32             System.out.println(result);  //输出方法
33
34             //传入2个参数一个人返回值
35
36             Class<?>[] typesB = new Class[2];
37             typesB[0] = String.class;
38             typesB[1] = Integer.TYPE;
39
40             Object[] ObjsB = new Object[2];
41             ObjsB[0] = new String("ZT");
42             ObjsB[1] = new Integer(520);
43
44             Method newMethod = clazz.getDeclaredMethod("test", typesB);
45             String res = newMethod.invoke(clazz, ObjsB).toString();
46
47             System.out.println(res);
48
49             //有传入的参数,没有返回值
50             Class<?>[] typesC = new Class[1];
51             typesC[0] = String.class;
52
53             Object[] objsC = new Object[1];
54             objsC[0] = new String("xiyoulele");
55
56             Method methodC = clazz.getDeclaredMethod("setTmpName", typesC);
57             methodC.invoke(clazz, objsC);
58
59             //无参数,无返回值
60             Method methodD = clazz.getDeclaredMethod("getVersion");
61             methodD.invoke(clazz);
62
63             classLoader.close();  //关闭类的加载器
64
65         } catch (Exception e)
66         {
67             e.printStackTrace();
68         }
69     }
70     //继承URLClassLoader来实现对jar文件的加载
71     static class MyClassLoader extends URLClassLoader
72     {
73         public MyClassLoader(URL[] urls)
74         {
75             super(urls);
76         }
77         public MyClassLoader(URL[] urls, ClassLoader parent)
78         {
79             super(urls, parent);
80         }
81         public void addJar(URL url)
82         {
83             this.addURL(url);
84         }
85     }
86 }
87 /*
88  * 需求:加载jar文件,动态调用里面的方法,该方法带有参数和返回值。
89  */ 

程序运行的结果:

时间: 2024-12-22 14:48:10

Java加载jar文件并调用jar文件当中有参数和返回值的方法的相关文章

JS中函数的本质,定义、调用,以及函数的参数和返回值

要用面向对象的方式去编程,而不要用面向过程的方式去编程 对象是各种类型的数据的集合,可以是数字.字符串.数组.函数.对象…… 对象中的内容以键值对方式进行存储 对象要赋值给一个变量 var cat={ "name":"喵1", "age":4, "family":["喵爸","喵妈"], "speak":function(){ console.log("喵喵

c++ ado 调用存储过程并得到输出参数和返回值

// AccessSqlserverByAdo.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <Windows.h> #include <iostream> #include <string> using namespace std; #import "C:\Program Files\Common Files\System\ado\msado15.dll" rename

059、Java中定义一个有参数无返回值的方法

01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public static void main(String[] args) { pay(10.0); // 调用方法 pay(-10.0); // 调用方法 } public static void pay(double money) { // 购买支付操作 if (money > 0.0) { // 现在已

使用requireJS加载不符合AMD规范的js文件:shim的使用方式和实现原理

我们知道在javascript中定义全局变量有2种方式,本质上是等价的,都是向window对象注入属性或者方法. // global.js var g_name = "aty"; window.g_age = 25; 当global.js加载的时候,浏览器的全局对象window就会多出2个属性:g_name和g_age. 我们编写一个js工具类或者是js框架,通常有2种方式: 方式1:dateUtil.js (function(window) { var DateUtils = {};

java动态加载指定的类或者jar包反射调用其方法

序言 有时候,项目中会用到java动态加载指定的类或者jar包反射调用其方法来达到模块的分离,使各个功能之间耦合性大大降低,更加的模块化,代码利用率更高.模式中的代理模式就用到java的这一机制.下边就让我们通过代码来看看如何实现此功能. 代码详细 package loadjarclass; import java.io.File; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoad

Java类加载机制——如何实现一个工程中不同模块加载不同版本的同名jar包。

如何实现一个工程中不同模块加载不同版本的同名jar包? 曾是阿里面试的时候遇到的一个面试题.当时就有点晕,如果是平时遇到这样的问题肯定是统一加载相同版本的就好了. 而如果系统特别庞大依赖冲突繁多,涉及多部门协调,真的有必要解决这样的问题. 这个问题困扰我很久,一直没有好的解决办法.最近研究java虚拟机.终于找到了答案. 在JVM里由类名和类加载器区别不同的Java类型.因此,JVM允许我们使用不同的加载器加载相同namespace的java类,而实际上这些相同namespace的java类可以

解决maven无法加载本地lib/下的jar包问题(程序包XXX不存在)

这次一个项目用到maven编译,我在本地开发的时候jar包都是放在WEB-INF/lib目录下,通过 BuildPath将jar包导入,然后用MyEclipse中的:maven package命令打成war包,这个war包在tomcat下能正常运行,war包下是有lib下的jar包的. 但是我往服务器上传的是项目源码,用SVN上传,然后服务器上用maven插件编译运行,编译时报错:找不到WEB-INF/lib下jar包.显然maven编译时不会自动加载WEB-INF/lib下的jar包. 项目的

java加载资源文件

className.class.getResourceAsStream 用法: 第一: 要加载的文件和.class文件在同一目录下,例如:com.x.y 下有类Test.class ,同时有资源文件config.properties 那么,应该有如下代码: //前面没有"/"代表当前类的目录 InputStream is1 = Test.class.getResourceAsStream("config.properties"); System.out.printl

java加载properties文件的六中基本方式实现

java加载properties文件的方式主要分为两大类:一种是通过import java.util.Properties类中的load(InputStream in)方法加载: 另一种是通过import java.util.ResourceBundle类的getBundle(String baseName)方法加载. 注意:一定要区分路径格式 实现代码如下: 1 package com.util; 2 3 import java.io.FileInputStream; 4 import jav