JDK源码(十五):Method

 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);
    }
}

更多精彩内容请关注微信公众号:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

徐楠_01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值