嗨,好久不见!
这几天小编遇到了一个问题,今天总算解决了,由此来给大家写一篇博客!今天的内容也是关于反射机制中的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中的方法是不能执行的,根据提示的错误,我发现是参数传递有问题,但是还未想出如何解决,请多指教。
好了,今天先写到这里,谢谢观看,也请对提建议!多谢!!
灯火阑珊处