深入理解Java中的反射机制和使用原理!详细解析invoke方法的执行和使用 (6)

DelegatingMethodAccessorImpl:

/* Delegates its invocation to another MethodAccessorImpl and can change its delegate at run time */ class DelegatingMethodAccessorImpl extends MethodAccessorImpl { private MethodAccessorImpl delegate; DelegatingMethodAccessorImpl(MethodAccessorImpl delegate) { setDelegate(delegate); } public Object invoke(Object obj, Object[] args) throws IllegalArgumentException, InvocationTargetException { return delegate.invoke(obj, args); } void setDelegate(MethodAccessorImpl delegate) { this.delegate = delegate; } }

DelegatingMethodAccessorImpl对象是一个中间层,方便在native版与Java版的MethodAccessor之间进行切换

native版MethodAccessor的Java方面的声明: sun.reflect.NativeMethodAccessorImpl

/* Used only for the first few invocations of a Method; afterward,switches to bytecode-based implementation */ class NativeMethodAccessorImpl extends MethodAccessorImpl { private Method method; private DelegatingMethodAccessorImpl parent; private int numInvocations; NativeMethodAccessorImpl(Method method) { this.method = method; } public Object invoke(Object obj, Object[] args) throws IllegalArgumentException, InvocationTargetException { /* We can't inflate methods belonging to vm-anonymous classes because that kind of class can't be referred to by name, hence can't be found from the generated bytecode */ if (++numInvocations > ReflectionFactory.inflationThreshold() && !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) { MethodAccessorImpl acc = (MethodAccessorImpl) new MethodAccessorGenerator(). generateMethod(method.getDeclaringClass(), method.getName(), method.getParameterTypes(), method.getReturnType(), method.getExceptionTypes(), method.getModifiers()); parent.setDelegate(acc); } return invoke0(method, obj, args); } void setParent(DelegatingMethodAccessorImpl parent) { this.parent = parent; } private static native Object invoke0(Method m, Object obj, Object[] args); }

每次NativeMethodAccessorImpl.invoke() 方法被调用时,程序调用计数器都会增加1, 看看是否超过阈值

如果超过则调用MethodAccessorGenerator.generateMethod() 来生成Java版的MethodAccessor的实现类

改变DelegatingMethodAccessorImpl所引用的MethodAccessorJava

经由DelegatingMethodAccessorImpl.invoke() 调用到的就是Java版的实现

JVM层invoke0方法

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zydsyj.html