zoukankan      html  css  js  c++  java
  • Java反射、动态加载(将java类名、方法、方法参数当做参数传递,执行方法)

    需求:将java类名、方法、方法参数当做参数传递,执行方法。可以用java的动态加载实现
     
    反射的过程如下:
     
     
    第一步:通过反射找到类并创建实例(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;
        }
    }

  • 相关阅读:
    大哥带我走渗透8--CSRF的应用
    大哥带我走渗透7----解析漏洞
    大哥带我走渗透6(下)---文件上传
    视频学习XSS
    大哥带我走渗透5--南方数据
    大哥带我走渗透4(中)----oracle报错注入
    大哥带我走渗透ii--时间盲注,布尔盲注
    SQL语言基础和数据库操作
    less-7
    less-6
  • 原文地址:https://www.cnblogs.com/meitian/p/8483452.html
Copyright © 2011-2022 走看看