-
反射的demo
package com.java.reflect; import java.lang.reflect.Method; /** * 反射調(diào)用的例子 * @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 -
反射的方法的執(zhí)行鏈路
為了看到反射調(diào)用鏈路我們以構造異常的方式打印堆棧信息:
package com.java.reflect; import java.lang.reflect.Method; /** * 反射調(diào)用的例子 * @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源碼分析-調(diào)用鏈路時序圖
反射調(diào)用鏈路時序圖.png源碼分析-調(diào)用鏈代碼
step 1:調(diào)用代碼
package com.java.reflect; import java.lang.reflect.Method; /** * 反射調(diào)用的例子 * @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執(zhí)行鏈路 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執(zhí)行鏈路
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.委派或者動態(tài)實現(xiàn)方式執(zhí)行調(diào)用,最終會調(diào)用到目標方法 // step 4:委派或者動態(tài)實現(xiàn)方式執(zhí)行調(diào)用 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 { // 如果不存在則創(chuàng)建 // step 3.1:創(chuàng)建MethodAccessor tmp = reflectionFactory.newMethodAccessor(this); setMethodAccessor(tmp); } return tmp; }step 3.1:創(chuàng)建MethodAccessor
public MethodAccessor newMethodAccessor(Method method) { checkInitted(); //如果不使用膨脹模式-Dsun.reflect.noInflation=true if (noInflation && !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) { //通過ASM動態(tài)生成 return new MethodAccessorGenerator(). generateMethod(method.getDeclaringClass(), method.getName(), method.getParameterTypes(), method.getReturnType(), method.getExceptionTypes(), method.getModifiers()); } else { // 委派模式,最終還是有NativeMethodAccessorImpl調(diào)用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 { // 如果執(zhí)行次數(shù)超過了ReflectionFactory.inflationThreshold()則使用動態(tài)實現(xiàn)方式 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); } // 委派模式最終執(zhí)行的是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:動態(tài)模式(靜態(tài)方法)
package com.java.reflect; import sun.reflect.MethodAccessorImpl; import java.lang.reflect.InvocationTargetException; /** * 動態(tài)實現(xiàn)方式: * 由ASM字節(jié)碼生成被調(diào)用方法的MethodAccessor類(相當于加了中間層,由中間層直接調(diào)用目標方法) * */ public class GeneratedMethodAccessor1 extends MethodAccessorImpl { public GeneratedMethodAccessor1() { } public Object invoke(Object var1, Object[] var2) throws InvocationTargetException { int var10000; try { //目標方法只有一個參數(shù) 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 { //目標方法是靜態(tài)方法(如果是實例方法則需要傳入的實例對象發(fā)起調(diào)用) ReflectionDemo.target(var10000); return null; } catch (Throwable var4) { throw new InvocationTargetException(var4); } } }step 4:動態(tài)模式(實例方法)
package sun.reflect; import com.java.reflect.ReflectionDemo; import java.lang.reflect.InvocationTargetException; /** * 實例方法生成動態(tài)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; // 入?yún)€數(shù)校驗 if (var2.length != 2) { throw new IllegalArgumentException(); } // 入?yún)㈩愋娃D換 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 { // 實例對象調(diào)用目標方法 return var10000.targetString(var10001, var10002); } catch (Throwable var4) { throw new InvocationTargetException(var4); } } } }
反射的實現(xiàn)原理
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
相關閱讀更多精彩內(nèi)容
- 前段時間看了笨神的 從一起GC血案談到反射原理一本,就把Java方法的反射機制實現(xiàn)擼了一遍。 一起GC血案談到反射...
- 簡書 占小狼轉載請注明原創(chuàng)出處,謝謝! “物有本末,事有始終。知其先后,則近道矣” 前段時間看了笨神的 從一起GC...
