嗨,好久不见!
这几天小编遇到了一个问题,今天总算解决了,由此来给大家写一篇博客!今天的内容也是关于反射机制中的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);
    }
}

输出结果如下:

int
studentMethod
class com.mec.about_reflection.StudentInvoke
这是学生的方法!学生的年龄:10
personMethod
class com.mec.about_reflection.PersonInvoke
object1:这是人类的方法!

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