需求:将java类名、方法、方法参数当做参数传递,执行方法。可以用java的动态加载实现
反射的过程如下:
![](https://images2018.cnblogs.com/blog/626983/201805/626983-20180516171306525-610027138.png)
第一步:通过反射找到类并创建实例(classname为要实例化的类名,由package和类名组成)
Class c = null; try { c = Class.forName(classname); } catch (Exception e) { e.printStackTrace(); } Object o = c.newInstance();//创建实例
classname由包名+类名组成,例如com.xx.logic.Testclass,一定要写包名全路径,否则有可能报错找不到类
两种实例化的方法:
1、newInstance
Class c=Class.forName(classname);
c.newInstance()
说明:适用于无参构造方法
2、getConstructor()
Class c=Class.forName(classname); c.getConstructor(String.class).newInstance(“Hello”);
getConstrutor里面为构造参数的Class类型,多个入参时传递Class[]数组
newInstance里为具体要传递的参数值
说明:适用于无参和有参的构造方法
第二步:找到方法(通过getMethod()方法),并执行
Method m = c.getMethod(methodname, paramstype);
methodname为要执行的方法名
paramstype为方法参数的类型,例如Integer或int等,传递的值为一个Class[]数组格式,可以通过getClass()获得类型
执行方法:
m.invoke(o, params);
m为Method要执行的方法
o为类实例
params为给方法传递的参数值,是一个数组,如果参数类型不固定可以用Object[]数组
遇到的问题:Object[]数组中增加了一个int型的值,通过getClass()方法获得的类型一直是Integer类型的,所以我就将int的手动给他类型赋值了int.class即可
调用方法(以下面例子封装的方法调用的):
public static void main(String args[]) { // new Eeflect().runMethod("util.hi", "test",new Object[]{});//不带参数的方法调用 // new Object[]{} new Eeflect().runMethod_classinstance(new hi(), "test2", "1,int:2");//传递一个实例,去执行方法 new Eeflect().runMethod("util.hi", "add", new Object[]{"1", "2"});//带参数的方法调用,但是变量是固定的 new Eeflect().runMethod_classname("util.hi", "test", "");//不带参数的方法 new Eeflect().runMethod_classname("util.hi", "add", "1,2");//String类型的方法 new Eeflect().runMethod_classname("util.hi", "test2", "1,int:2");//String和int两种类型的方法 System.out.println(new Object[]{}.getClass() ); new Eeflect().runMethod_classname("util.hi", "print", "StringArrays:1、2、3");//不固定参数...的方法,使用数组传递 }
下面是我写的例子:因为我想把参数使用字符串传递进来所以麻烦了一些
package util; import java.lang.reflect.Method; import java.net.URLClassLoader; import java.util.Arrays; import java.util.HashMap; import java.util.Map; //动态执行方法,但是不能调用方法的方法 //getparam_valueandetype():解析参数,分解为参数值和参数类型数组 //runMethod_classname():传递类名,自动实例化执行方法 //runMethod_classinstance():传递类实例,执行方法 public class Eeflect { public Class getClass(String classname) { // URLClassLoader classloader = (URLClassLoader) ClassLoader.getSystemClassLoader(); Class c = null; try { c = Class.forName(classname); // c = classloader.loadClass(classname); } catch (Exception e) { e.printStackTrace(); } return c; } public Map getparam_valueandetype(String params) {//入参字符串,将其解析为参数class类型数组和参数值数组 //params使用英文逗号隔开,使用:分隔参数类型和值,例如abcd,int 1,test,int:2,StringArrays:1、2、3 Object[] paramlist = new Object[]{};//存储变量值 Class[] classtype = new Class[]{};//存储变量类型 Map result = new HashMap(); if (!params.equals("")) {//传递了参数params走这里 String[] paramslist_temp = params.split(",|,"); int num = paramslist_temp.length; paramlist = new Object[num]; classtype = new Class[num]; for (int i = 0; i < num; i++) { String[] param_type_value = paramslist_temp[i].toString().split(":");//判断参数是否有类型定义 if (param_type_value.length > 1) { String param_type = param_type_value[0]; String param_value = param_type_value[1]; if (param_type.equalsIgnoreCase("int")) { // System.out.println("value=" + param_value); paramlist[i] = Integer.parseInt(param_value); classtype[i] = int.class; } else if (param_type.equalsIgnoreCase("string")) { paramlist[i] = param_value; } else if (param_type.equalsIgnoreCase("stringarrays")) { paramlist[i] = param_value.split("、"); classtype[i] = String[].class; } else { System.out.println("变量类型不支持,目前只支持int强转,当前变量的类型为:" + param_type); return result; } } else { paramlist[i] = paramslist_temp[i]; classtype[i] = paramslist_temp[i].getClass(); } } } result.put("paramlist", paramlist); result.put("classtype", classtype); return result; } public boolean runMethod_classname(String classname, String methodname, String params) {//传递classname字符串,执行方法 boolean result = false; Map paraminfo = this.getparam_valueandetype(params); if (paraminfo == null) { return result; } Object[] paramlist = (Object[]) paraminfo.get("paramlist"); Class[] classtype = (Class[]) paraminfo.get("classtype"); result=this.runMethod(classname, methodname, paramlist, classtype); return result; } public boolean runMethod(String classname, String methodname, Object[] params, Class[] paramstype) {//通过类名获得类实例,去执行方法 boolean result = false; try { Class c = this.getClass(classname); if (c != null) { Object o = c.newInstance(); Method m = c.getMethod(methodname, paramstype); m.invoke(o, params); result = true; } } catch (Exception e) { e.printStackTrace(); } return result; } public boolean runMethod_classinstance(Object classinstance, String methodname, String params) {//传递class实例,执行方法 boolean result = false; Map paraminfo = this.getparam_valueandetype(params); Object[] paramlist = new Object[]{}; Class[] classtype = new Class[]{}; if (paraminfo != null) { paramlist = (Object[]) paraminfo.get("paramlist"); classtype = (Class[]) paraminfo.get("classtype"); } result = this.runMethod_hasclass(classinstance, methodname, paramlist, classtype); // if(!result){ // System.out.println("runMethod_classinstance失败了"); // } return result; } public boolean runMethod_hasclass(Object classinstance, String methodname, Object[] params, Class[] paramstype) {//通过类实例,去执行它的方法 boolean result = false; try { Class c = classinstance.getClass(); Method m = c.getMethod(methodname, paramstype); m.invoke(classinstance, params); result = true; } catch (Exception e) { e.printStackTrace(); } return result; } public boolean runMethod(String classname, String methodname, Object[] params) { boolean result = false; try { Class paramlist[] = null; if (params != null) {// int len = params.length; paramlist = new Class[len]; for (int i = 0; i < len; ++i) { paramlist[i] = params[i].getClass(); if (paramlist[i].toString().equals("class java.lang.Integer")) { paramlist[i] = int.class; } } } Class c = this.getClass(classname); if (c != null) { Object o = c.newInstance(); Method m = c.getMethod(methodname, paramlist); m.invoke(o, params); result = true; } } catch (Exception e) { e.printStackTrace(); } return result; } }