深入理解java反射机制中Method类中的invoke()方法

1.先说明Method类中的几个重要的属性

1)Method类型的root属性:

可以理解为每一个 java方法都有唯一的一个Method对象,这个对象就是root,我们可以利用反射创建java方法的众多的Method类的对象,这些对象指向root,可以理解为root的镜像。

2)MethodAccessor类型的 methodAccessor属性:

每一个Method对象有一个root属性,每一个root对象里有一个methodAccessor对象。我们获取的Method相当于root的镜像,可以共用methodAccessor对象。这个对象由ReflectionFactory来创建

2.源码分析

首先是判断override是true还是false,override属性是Method类的父类Executable的父类AccessibleObject的一个属性,用来判断是否要进行访问权限判断。默认为false,我们可以通过setAccessible()方法来设置override的值。它里面有一个setAccessible0()方法:

如果override设置为true,则可以忽略访问权限的限制,直接调用。如果为false,则通过执行Reflection.quickCheckMemberAccess(clazz, modifiers)这个方法来判断我们需要调用的方法是不是public类型的(还是访问权限的问题,public,protected,private的范围)。如果不是public类型的,则我们通过 Class<?> caller = Reflection.getCallerClass();来获取该方法的Class对象。然后调用checkAccess(caller, clazz, obj, modifiers);进行访问权限的校验。

在这个访问权限的校验方法中我们用到了缓存,即第一次校验后就存放到缓存中,下次进行缓存校验时如果还是同一个类来校验,则不校验,直接返回。但是如果下一次不是同一个类,我们会覆盖缓存中的类。

访问权限的判断校验后就是重点:

首先我们会获取methodAccessor对象,因为每个java方法的methodAccessor唯一。此处我们通过acquireMethodAccessor()来生成methodAccessor对象:

如果root中的methodAccessor不为空,即上次调用invoke()已经为root中的methodAccessor赋值了。否则通过reflectionFactory.newMethodAccessor(this);来创建methodAccessor对象,然后调用setMethodAccessor(tmp);为root中的methodAccessor赋值。然后通过methodAccessor对象的invoke()来完成对方法的调用。实际上Method.invoke()不是自己来完成反射调用逻辑的,而是委托给MethodAccessor的invoke()来实现的。每个java方法只有一个Method对象作为root,同样,对应的methodAccessor对象也只能是一个。我们每次创建返回的Method对象都是包装了root的对象。


  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值