java反射Method#invoke分析(1)

java反射Method#invoke分析(1)public class SimpleBean { public String doWork(String work) {

欢迎大家来到IT世界,在知识的湖畔探索吧!

public class SimpleBean {
    public String doWork(String work) {
        System.out.println("参数:" + work);
        return work;
    }
}

欢迎大家来到IT世界,在知识的湖畔探索吧!

欢迎大家来到IT世界,在知识的湖畔探索吧!// java反射的基本调用方式
public class InvokeMainTest {
    public static void main(String[] args) throws Exception{
        Class<?> aClass = Class.forName("xxx.SimpleBean");
        Object o = aClass.newInstance();
        Method method = aClass.getDeclaredMethod("doWork", new Class[] {String.class});
        method.invoke(o, "吃蛋糕");
    }
}

我们来分析一下invoke的流程

Method.invoke方法:首先创建方法的访问器

public Object invoke(Object obj, Object... args)
    throws IllegalAccessException, IllegalArgumentException,
       InvocationTargetException
{
		……
   // 获取方法的访问器
   ma = acquireMethodAccessor();
		……
    return ma.invoke(obj, args);
}
欢迎大家来到IT世界,在知识的湖畔探索吧!private MethodAccessor acquireMethodAccessor() {
				……
        // 创建方法访问器的具体实现
        tmp = reflectionFactory.newMethodAccessor(this);
  			……
    }

    return tmp;
}
// 本地方法访问器
NativeMethodAccessorImpl var2 = new NativeMethodAccessorImpl(var1);//var1是method
// 委托方法访问器
DelegatingMethodAccessorImpl var3 = new DelegatingMethodAccessorImpl(var2);
var2.setParent(var3);

NativeMethodAccessorImplDelegatingMethodAccessorImpl这两个访问器是最终来代理调用Method的类

最终Method.invoke中的invoke会形成这样的调用关系:

method.invoke->

DelegatingMethodAccessorImpl->

NativeMethodAccessorImpl->

nativeMethod

具体的调用实现在NativeMethodAccessorImpl内。

public Object invoke(Object var1, Object[] var2) throws IllegalArgumentException, InvocationTargetException {
  // 当前method调用超过15次,使用asm方式在JVM中生成新的字节码类,用来代理调用method
  if (++this.numInvocations > ReflectionFactory.inflationThreshold() && !ReflectUtil.isVMAnonymousClass(this.method.getDeclaringClass())) {
        MethodAccessorImpl var3 = (MethodAccessorImpl)(new MethodAccessorGenerator()).generateMethod(this.method.getDeclaringClass(), this.method.getName(), this.method.getParameterTypes(), this.method.getReturnType(), this.method.getExceptionTypes(), this.method.getModifiers());
        this.parent.setDelegate(var3);
    }
	  // 15次之内调用本地方法
    return invoke0(this.method, var1, var2);
}

this.parent.setDelegate(var3) 这个NativeMethodAccessorImpl通过生成新的类替换了自己

method.invoke->

DelegatingMethodAccessorImpl->

新MethodAccessorImpl->

invoke

java反射Method#invoke分析(1)

整体调用流程

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/48981.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信