java.lang.reflect.Method类描述的是类的方法信息(包括:方法修饰符、方法名称、参数列表等等)。
在java.lang.Class获取Method对象的方法总共有四个:
我们可以根据方法名称得到该方法的Method对象,然后调用Method对象的invoke方法实现方法的调用,这也是Method最重要的用法。
invoke(Object obj, Object... args)
@CallerSensitive
public Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException
{
//override表示此对象是否重写语言级访问检查。初始化为“false”
if (!override) {
//检查是否为public
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
//判断caller是否有权限访问该方法
checkAccess(caller, clazz, obj, modifiers);
}
}
MethodAccessor ma = methodAccessor;// read volatile
if (ma == null) {
ma = acquireMethodAccessor();
}
return ma.invoke(obj, args);
}
Method类的invoke(Object obj,Object args[])方法接收的参数必须为对象,如果参数为基本类型数据,必须转换为相应的包装类型的对象。invoke()方法的返回值总是对象,如果实际被调用的方法的返回类型是基本类型数据,那么invoke()方法会把它转换为相应的包装类型的对象,再将其返回。
如果底层方法是静态的,则忽略指定的obj参数。它可能为空。如果基础方法所需的形式参数个数为0,则提供的args数组的长度可以为0或null。如果底层方法是实例方法,则使用Java语言规范第二版第15.12.4.4节中所述的动态方法查找调用它;特别是,将根据目标对象的运行时类型进行重写。如果基础方法是静态的,则声明该方法的类将被初始化(如果尚未初始化)。如果该方法正常完成,则将返回值返回给invoke的调用方;如果该值具有基本类型,则首先将其适当地包装在对象中。但是,如果该值具有基本类型数组的类型,则数组的元素不包装在对象中;换句话说,将返回基本类型数组。如果基础方法返回类型为void,则调用返回null。
在invoke方法中,override属性是Method的父类AccessibleObject中声明的变量,使得程序可以控制是否跳过访问权限的检查。在acquireMethodAccessor()方法中MethodAccessor的创建是通过反射工厂ReflectionFactory的newMethodAccessor(Method)方法来创建的。
private MethodAccessor acquireMethodAccessor() {
//检查是否已经创建
MethodAccessor tmp = null;
if (root != null) tmp = root.getMethodAccessor();
if (tmp != null) {
methodAccessor = tmp;
} else {
// 否则就制造一个并传播到根部
tmp = reflectionFactory.newMethodAccessor(this);
setMethodAccessor(tmp);
}
return tmp;
}
MethodAccessor.invoke最终调用底层方法
private static native Object invoke0(Method var0, Object var1, Object[] var2);
public class MethodDemo {
public static void main(String[] args) throws Exception {
Student student = Student.class.newInstance();
//调用public方法
Method sum = Student.class.getDeclaredMethod("sum", int.class, int.class);
int s = (int) sum.invoke(student, 2, 4);
System.out.println(s);
//调用public static方法
Method min = Student.class.getDeclaredMethod("min", int.class, int.class);
int m = (int) min.invoke(null, 2, 4);
System.out.println(m);
//调用private方法
Method info = Student.class.getDeclaredMethod("info");
//设置可访问
info.setAccessible(true);
String in = (String) info.invoke(student);
System.out.println(in);
}
}
更多精彩内容请关注微信公众号: