今天带大家一起学习Java反射机制中简单的invoke()方法(三)

来源:互联网 发布:php pos点餐系统 编辑:程序博客网 时间:2024/06/07 06:55

嗨,好久不见!
这几天小编遇到了一个问题,今天总算解决了,由此来给大家写一篇博客!今天的内容也是关于反射机制中的invoke方法。
首先,给两个简单的类,包含继承关系:
PersonInvoke类

package com.mec.about_reflection;public class PersonInvoke {    public PersonInvoke() {    }    private String personMethod() {//一个私有方法        return "这是人类的方法!";    }}

再给一个类:StudentInvoke类(包含继承关系)

package com.mec.about_reflection;public class StudentInvoke extends PersonInvoke{    public StudentInvoke() {    }    private String studentMethod(int age) {        return "这是学生的方法!" + "学生的年龄:" + age;    }}

接下来,对于这两个类进行invoke方法的书写:

package com.mec.about_reflection.invoke;import java.lang.reflect.Method;import com.mec.about_reflection.PersonInvoke;import com.mec.about_reflection.StudentInvoke;    public class Invoke {        //通过类名、方法名、参数执行这个方法        public Object invoke(String className, String methodName ,Object ...args) {            Object object = null;            try {                //对这个类实例化一个对象                object = Class.forName(className).newInstance();                //通过invoke()执行这个类的方法                System.out.println(invoke(object, methodName, args));            } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {                e.printStackTrace();            }            return invoke(null, methodName, args);        }    //可以看做是对上述方法的重载,注意第一个参数不同    public  Object invoke(Object obj, String methodName, Object ... args) {        //通过数组的方式得到这个参数的个数        Class[] parameterTypes = new Class[args.length];        for(int i = 0; i < args.length;i++) {                //获取每个参数的类型                parameterTypes[i] = args[i].getClass();//对于Integer.class类型的参数进行转换类型,这是小芳经过测试得到的结论(我的djk为1.8)                if(parameterTypes[i].equals(Integer.class)) {                    parameterTypes[i] = int.class;                }//对参数类型进行输出                                     System.out.println(parameterTypes[i]);            }        try {                   //通过类、方法名称、参数类型得到这个方法                Method method = getMethod(obj.getClass(),methodName,parameterTypes);                 //让这个方法变为可见的(具体是让private修饰的方法可见)                method.setAccessible(true);                 //返回这个方法的执行结果                       return method.invoke(obj, args);           } catch (Exception e) {        }        return null;    }    @SuppressWarnings("unchecked")    public Method getMethod(Class clazz, String methodName,parameterTypes) {    //自己写的获取方法的函数        //底下两行进项简单的输出        System.out.println(methodName);        System.out.println(clazz);        //底下这个操作是遍历这些类,这里的写法是有继承关系的写法(clazz.getSurperClass()),如果没有继承关系也可以写为if( clazz != Object.class).        for(; clazz != Object.class; clazz = clazz.getSurperClass()) {            try {                //返回这个方法                return clazz.getDeclaredMethod(methodName, parameterTypes);            } catch (NoSuchMethodException | SecurityException e) {                e.printStackTrace();            }         }        return null;    }

底下是在main函数中测试这个方法:

public static void main(String[] args) {        Invoke invoke = new Invoke();        Object object = new StudentInvoke();        System.out.println(invoke.invoke(object, "studentMethod",10));        Object object2 = new PersonInvoke();        Object object1 = invoke.invoke(object2,"personMethod");        System.out.println("object1:" +object1);    }}

输出结果如下:

intstudentMethodclass com.mec.about_reflection.StudentInvoke这是学生的方法!学生的年龄:10personMethodclass com.mec.about_reflection.PersonInvokeobject1:这是人类的方法!

总结:
1.这种方法相对于反射机制提供的内部invoke()方法比较繁琐,但是也是通过自己对反射机制的理解写出的方法;
2.对于getMethod()方法中的循环中是有问题的,如果你有兴趣测试我的代码,不会发现这个继承关系是不起作用的,你也可以从我的main()中看出来,我在给两个类都进行了new操作之后,才出现了正确结果,如果用单一的子类对象,对于StudentInvoke中的方法是不能执行的,根据提示的错误,我发现是参数传递有问题,但是还未想出如何解决,请多指教。
好了,今天先写到这里,谢谢观看,也请对提建议!多谢!!
灯火阑珊处

原创粉丝点击