前言

前面总结了,java反射的一些函数的相关用法,本篇主要总结如何利用这些函数来构造执行函数。

重要方法

其实上篇总结过,这里再加几个

newInstance()

该方法属于 Class 类,执行后返回一个 Object ,可以利用这个方法来实例化对应的类,作用就是调用这个类的无参构造函数。但要求要实例化的类必须要有无参构造函数,并且这个构造函数不是私有的。

Runtime类的分析

进入 Runtime 类中可以看到

image-20221009132921776

发现 Runtime 类使用的单例模式,即只能通过 getRuntime() 方法来获取 Runtime 对象。同时注意 getRuntime 对象是静态方法,即可以直接通过 类名.方法名 的方法调用。

java执行命令

Runtime run = Runtime.getRuntime();//获取 Runtime 对象
run.exec("calc");//执行calc命令弹出计算器

getMethod()

该方法可获取一个 Method 对象,即获取类中的方法,通常要和 invoke() 方法一起使用,这里重点关注下它的各项参数

image-20221009133822176

第一个参数 name 是所要获取方法的方法名,第二个参数 parameterTypes 是所获得到的方法中参数的类型, parameterTypes 是个 Class 类型的数组,用的是java的 可变长参数 的写法, <?> 是泛型的表示,这里不探讨。

即 参数类型 Class<?>... parameterTypes 其实等价于 Class<?>[] parameterTypes 。传递的对应参数是所获取方法的对应的参数类型。比如 Runtime 中的 exec(String command) 函数,获取它就是

Class clazz = Class.forName("java.lang.Runtime");
Method cmd = clazz.getMethod("exec", String.class);

invoke()

invoke() 方法用于执行 getMethod 获取的方法,看看它的相关参数

image-20221009135348425

第一个参数是函数所在的 类对象 ,第二个参数是所执行的函数的对象参数

依旧拿 exec(String command) 方法来说

Runtime run = Runtime.getRuntime();//获取Runtime对象
Class clazz = Class.forName("java.lang.Runtime");
Method cmd = clazz.getMethod("exec", String.class);
cmd.invoke(run, "calc");//执行函数

如果执行的方法是静态方法,那么 invoke 的第一个 obj 参数将被忽略

image-20221010152927086

比如我们要执行上面所说的 Runtime 类中的静态方法 getRuntime() 去获取对象

Class clazz = Class.forName("java.lang.Runtime");
//调用静态方法getRuntime()获取Runtime对象
Runtime run = (Runtime) clazz.getMethod("getRuntime").invoke(null);//调用的是静态方法,invoke()里参数随便写一个就行,会忽略第一个参数
run.exec("calc");

等价于 Runtime.getRuntime().exec("calc");

利用反射执行命令

总结上面的 getMethod invoke ,大白话说就是我们一般这个样执行函数

Object.Method(arg1, arg2, ...) ,或执行静态方法 Class.Method(arg1, arg2, ...)

用反射就是 Method.invoke(Object, arg1, arg2, ...) , Method.invoke(Class, arg1, arg2, ...)

所以可以利用纯反射执行命令

//获取 Runtime 类