反射的实现原理
2018-09-08 本文已影响0人
5473631d8226
-
反射的demo
package com.java.reflect; import java.lang.reflect.Method; /** * 反射调用的例子 * @author helenlee * @date 2018/9/4 */ public class ReflectionDemo { public static void main(String[] args) throws Exception { Class<?> clzss = Class.forName("com.java.reflect.ReflectionDemo"); // target方法是访问权限是public, // 如果是private则需要通过clzss.getDeclaredMethod()获取 Method target = clzss.getMethod("target", int.class); target.invoke(null, 128); } public static void target(int i) { System.out.println("invoke target method"); } } ###输出 $ javac com/java/reflect/ReflectionDemo.java $ java com/java/reflect/ReflectionDemo invoke target method
-
反射的方法的执行链路
为了看到反射调用链路我们以构造异常的方式打印堆栈信息:
package com.java.reflect; import java.lang.reflect.Method; /** * 反射调用的例子 * @author helenlee * @date 2018/9/4 */ public class ReflectionDemo { public static void main(String[] args) throws Exception { Class<?> clzss = Class.forName("com.java.reflect.ReflectionDemo"); // target方法是访问权限是public, // 如果是private则需要通过clzss.getDeclaredMethod()获取 Method target = clzss.getMethod("target", int.class); target.invoke(null, 128); } public static void target(int i) { //输出堆栈信息 new Exception("#" + i).printStackTrace(); System.out.println("invoke target method"); } } ----------------输出--------------- $ javac com/java/reflect/ReflectionDemo.java $ java com/java/reflect/ReflectionDemo java.lang.Exception: #128 at com.java.reflect.ReflectionDemo.target(ReflectionDemo.java:18) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.java.reflect.ReflectionDemo.main(ReflectionDemo.java:14) invoke target method
源码分析-调用链路时序图
反射调用链路时序图.png
源码分析-调用链代码
step 1:调用代码
package com.java.reflect; import java.lang.reflect.Method; /** * 反射调用的例子 * @author helenlee * @date 2018/9/4 */ public class ReflectionDemo { public static void main(String[] args) throws Exception { Class<?> clzss = Class.forName("com.java.reflect.ReflectionDemo"); // target方法是访问权限是public, // 如果是private则需要通过clzss.getDeclaredMethod()获取 Method target = clzss.getMethod("target", int.class); // step 2:Method执行链路 target.invoke(null, 128); } public static void target(int i) { new Exception("#" + i).printStackTrace(); System.out.println("invoke target method"); } public String targetString(int i,String name){ new Exception("#" + i).printStackTrace(); System.out.println("invoke target method"); return name; } }
step 2:Method执行链路
package java.lang.reflect; import sun.reflect.CallerSensitive; import sun.reflect.MethodAccessor; import sun.reflect.Reflection; import sun.reflect.generics.repository.MethodRepository; import sun.reflect.generics.factory.CoreReflectionFactory; import sun.reflect.generics.factory.GenericsFactory; import sun.reflect.generics.scope.MethodScope; import sun.reflect.annotation.AnnotationType; import sun.reflect.annotation.AnnotationParser; import java.lang.annotation.Annotation; import java.lang.annotation.AnnotationFormatError; import java.nio.ByteBuffer; public final class Method extends Executable { private Class<?> clazz; private int modifiers; private volatile MethodAccessor methodAccessor; private Method root; @CallerSensitive public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { // 1.权限检查 if (!override) { if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { Class<?> caller = Reflection.getCallerClass(); checkAccess(caller, clazz, obj, modifiers); } } // 2.获取委派的对象 MethodAccessor ma = methodAccessor; if (ma == null) { // step 3:获取委派对象 ma = acquireMethodAccessor(); } // 3.委派或者动态实现方式执行调用,最终会调用到目标方法 // step 4:委派或者动态实现方式执行调用 return ma.invoke(obj, args); } }
step 3:获取委派对象
private MethodAccessor acquireMethodAccessor() { MethodAccessor tmp = null; // 如果缓存中有则直接返回 if (root != null) tmp = root.getMethodAccessor(); if (tmp != null) { methodAccessor = tmp; } else { // 如果不存在则创建 // step 3.1:创建MethodAccessor tmp = reflectionFactory.newMethodAccessor(this); setMethodAccessor(tmp); } return tmp; }
step 3.1:创建MethodAccessor
public MethodAccessor newMethodAccessor(Method method) { checkInitted(); //如果不使用膨胀模式-Dsun.reflect.noInflation=true if (noInflation && !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) { //通过ASM动态生成 return new MethodAccessorGenerator(). generateMethod(method.getDeclaringClass(), method.getName(), method.getParameterTypes(), method.getReturnType(), method.getExceptionTypes(), method.getModifiers()); } else { // 委派模式,最终还是有NativeMethodAccessorImpl调用Native方法完成 NativeMethodAccessorImpl acc = new NativeMethodAccessorImpl(method); DelegatingMethodAccessorImpl res = new DelegatingMethodAccessorImpl(acc); acc.setParent(res); return res; } }
step 4:委派模式
class DelegatingMethodAccessorImpl extends MethodAccessorImpl { private MethodAccessorImpl delegate; DelegatingMethodAccessorImpl(MethodAccessorImpl delegate) { setDelegate(delegate); } public Object invoke(Object obj, Object[] args) throws IllegalArgumentException, InvocationTargetException { // delegate是一个NativeMethodAccessorImpl对象 return delegate.invoke(obj, args); } void setDelegate(MethodAccessorImpl delegate) { this.delegate = delegate; } } class NativeMethodAccessorImpl extends MethodAccessorImpl { private final Method method; private DelegatingMethodAccessorImpl parent; private int numInvocations; NativeMethodAccessorImpl(Method method) { this.method = method; } public Object invoke(Object obj, Object[] args) throws IllegalArgumentException, InvocationTargetException { // 如果执行次数超过了ReflectionFactory.inflationThreshold()则使用动态实现方式 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); } // 委派模式最终执行的是native方法(整个过程Java->C->Java) return invoke0(method, obj, args); } void setParent(DelegatingMethodAccessorImpl parent) { this.parent = parent; } private static native Object invoke0(Method m, Object obj, Object[] args); }
step 4:动态模式(静态方法)
package com.java.reflect; import sun.reflect.MethodAccessorImpl; import java.lang.reflect.InvocationTargetException; /** * 动态实现方式: * 由ASM字节码生成被调用方法的MethodAccessor类(相当于加了中间层,由中间层直接调用目标方法) * */ public class GeneratedMethodAccessor1 extends MethodAccessorImpl { public GeneratedMethodAccessor1() { } public Object invoke(Object var1, Object[] var2) throws InvocationTargetException { int var10000; try { //目标方法只有一个参数 if (var2.length != 1) { throw new IllegalArgumentException(); } Object var3 = var2[0]; if (var3 instanceof Byte) { var10000 = (Byte)var3; } else if (var3 instanceof Character) { var10000 = (Character)var3; } else if (var3 instanceof Short) { var10000 = (Short)var3; } else { if (!(var3 instanceof Integer)) { throw new IllegalArgumentException(); } var10000 = (Integer)var3; } } catch (NullPointerException | ClassCastException var5) { throw new IllegalArgumentException(var5.toString()); } try { //目标方法是静态方法(如果是实例方法则需要传入的实例对象发起调用) ReflectionDemo.target(var10000); return null; } catch (Throwable var4) { throw new InvocationTargetException(var4); } } }
step 4:动态模式(实例方法)
package sun.reflect; import com.java.reflect.ReflectionDemo; import java.lang.reflect.InvocationTargetException; /** * 实例方法生成动态MethodAccessor类 * 如:public String targetString(int i,String name); */ public class GeneratedMethodAccessor1 extends MethodAccessorImpl { public GeneratedMethodAccessor1() { } public Object invoke(Object var1, Object[] var2) throws InvocationTargetException { // 传入的实例对象不能为空 if (var1 == null) { throw new NullPointerException(); } else { ReflectionDemo var10000; int var10001; String var10002; try { // 强转实例对象 var10000 = (ReflectionDemo)var1; // 入参个数校验 if (var2.length != 2) { throw new IllegalArgumentException(); } // 入参类型转换 Object var3 = var2[0]; if (var3 instanceof Byte) { var10001 = (Byte)var3; } else if (var3 instanceof Character) { var10001 = (Character)var3; } else if (var3 instanceof Short) { var10001 = (Short)var3; } else { if (!(var3 instanceof Integer)) { throw new IllegalArgumentException(); } var10001 = (Integer)var3; } var10002 = (String)var2[1]; } catch (NullPointerException | ClassCastException var5) { throw new IllegalArgumentException(var5.toString()); } try { // 实例对象调用目标方法 return var10000.targetString(var10001, var10002); } catch (Throwable var4) { throw new InvocationTargetException(var4); } } } }