public class SimpleBean {
public String doWork(String work) {
System.out.println("参数:" + work);
return work;
}
}
// 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);
}
private MethodAccessor acquireMethodAccessor() {
……
// 创建方法访问器的具体实现
tmp = reflectionFactory.newMethodAccessor(this);
……
}
return tmp;
}
// 本地方法访问器
NativeMethodAccessorImpl var2 = new NativeMethodAccessorImpl(var1);//var1是method
// 委托方法访问器
DelegatingMethodAccessorImpl var3 = new DelegatingMethodAccessorImpl(var2);
var2.setParent(var3);
NativeMethodAccessorImpl和DelegatingMethodAccessorImpl这两个访问器是最终来代理调用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