Method的invoke方法初步了解

Java调试过程中,我们有时候会需要对JVM运行过程中哪出了问题进行调试,先从最基础的了解。

 

我们都知道Java框架中方法的调用基本上都是通过反射机制来实施的,具体流程如下:

 

1、方法的调用先检查AccessibleObject的override属性是否是true,如果是则表明该方法是复写的方法,可以忽略访问权限的限制,直接访问。如果不是则进行访问权限检测,用sun.reflect.Reflection的quickCheckMemberAccess方法先检验是不是public,如果不是则再用sun.reflect.Reflection.getCallerClass()方法获得调用这个方法的Class,然后再做是否有权限访问的校验,检验之后会将结果缓存

 

2、sun.reflect.ReflectionFactory调用方法newMethodAccessor创建方法访问器时,私有静态变量noInflation如果为true则直接返回MethodAccessorGenerator创建的一个MethodAccessor,否则返回DelegatingMethodAccessorImpl类,并将DelegatingMethodAccessorImpl与一个NativeMethodAccessorImpl互相引用。但DelegatingMethodAccessorImpl执行invoke方法的时候又委托给NativeMethodAccessorImpl。

 

3、NativeMethodAccessorImpl的invkoe方法,NativeMethodAccessorImpl类中有一个计数器numInvocations,每调用一次方法自增加1一次,当比 ReflectionFactory的静态常量inflationThreshold(15)大的时候,用MethodAccessorGenerator创建一个MethodAccessor,并把之前的DelegatingMethodAccessorImpl引用替换为现在新创建的MethodAccessorImpl(MethodAccessorGenerator创建的MethodAccessor强制类型转换为MethodAccessorImpl),其中MethodAccessorGenerator使用了asm(assembly)字节码动态加载技术,汇编命令有更高的执行效率。

4、Method类中的invoke方法拿到的MethodAccessor对象是被volatile变量。

总结:一个方法可以生成多个Method对象,但只有一个root对象,主要用于持有一个MethodAccessor对象,这个对象也可以认为一个方法只有一个,相当于是static的。因为Method的invoke是交给MethodAccessor执行的

我们在对加了@Test注解的方法进行debug时,JUnitCore类定义了一系列方法来启动JUnit完成对测试类的反射执行,InvokeMethod类的evaluate方法会使用测试方法(FrameworkMethod类)的invokeExplosively调用该方法的返回结果。

 

备注:

1、

访问权限当前类同一包子类其他包
public
protect×
friendly(默认)××
private×××

        

2、源码中很多方法用native修饰符,这种修饰符表明方法是该方法的实现由非java语言实现(A native method is a Java method whose implementation is provided by non-java code.)。当被native修饰时,描述符块会有一个指向该实现方法的指针。

 

3、参考:https://www.cnblogs.com/onlywujun/p/3519037.html,文中的Reflection.getCallerClass(1)方法在JDK8 版本已过时(加上@Deprecated注解),使用静态本地方法getCallerClass()加上@CallerSensitive解决通过双重反射提升权限的漏洞

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值