-
反射的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方法是訪問(wèn)權(quán)限是public, // 如果是private則需要通過(guò)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)用鏈路我們以構(gòu)造異常的方式打印堆棧信息:
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方法是訪問(wèn)權(quán)限是public, // 如果是private則需要通過(guò)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)用鏈路時(shí)序圖
反射調(diào)用鏈路時(shí)序圖.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方法是訪問(wèn)權(quán)限是public, // 如果是private則需要通過(guò)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.權(quán)限檢查 if (!override) { if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { Class<?> caller = Reflection.getCallerClass(); checkAccess(caller, clazz, obj, modifiers); } } // 2.獲取委派的對(duì)象 MethodAccessor ma = methodAccessor; if (ma == null) { // step 3:獲取委派對(duì)象 ma = acquireMethodAccessor(); } // 3.委派或者動(dòng)態(tài)實(shí)現(xiàn)方式執(zhí)行調(diào)用,最終會(huì)調(diào)用到目標(biāo)方法 // step 4:委派或者動(dòng)態(tài)實(shí)現(xiàn)方式執(zhí)行調(diào)用 return ma.invoke(obj, args); } }step 3:獲取委派對(duì)象
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())) { //通過(guò)ASM動(dòng)態(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是一個(gè)NativeMethodAccessorImpl對(duì)象 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ù)超過(guò)了ReflectionFactory.inflationThreshold()則使用動(dòng)態(tài)實(shí)現(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方法(整個(gè)過(guò)程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:動(dòng)態(tài)模式(靜態(tài)方法)
package com.java.reflect; import sun.reflect.MethodAccessorImpl; import java.lang.reflect.InvocationTargetException; /** * 動(dòng)態(tài)實(shí)現(xiàn)方式: * 由ASM字節(jié)碼生成被調(diào)用方法的MethodAccessor類(lèi)(相當(dāng)于加了中間層,由中間層直接調(diào)用目標(biāo)方法) * */ public class GeneratedMethodAccessor1 extends MethodAccessorImpl { public GeneratedMethodAccessor1() { } public Object invoke(Object var1, Object[] var2) throws InvocationTargetException { int var10000; try { //目標(biāo)方法只有一個(gè)參數(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 { //目標(biāo)方法是靜態(tài)方法(如果是實(shí)例方法則需要傳入的實(shí)例對(duì)象發(fā)起調(diào)用) ReflectionDemo.target(var10000); return null; } catch (Throwable var4) { throw new InvocationTargetException(var4); } } }step 4:動(dòng)態(tài)模式(實(shí)例方法)
package sun.reflect; import com.java.reflect.ReflectionDemo; import java.lang.reflect.InvocationTargetException; /** * 實(shí)例方法生成動(dòng)態(tài)MethodAccessor類(lèi) * 如:public String targetString(int i,String name); */ public class GeneratedMethodAccessor1 extends MethodAccessorImpl { public GeneratedMethodAccessor1() { } public Object invoke(Object var1, Object[] var2) throws InvocationTargetException { // 傳入的實(shí)例對(duì)象不能為空 if (var1 == null) { throw new NullPointerException(); } else { ReflectionDemo var10000; int var10001; String var10002; try { // 強(qiáng)轉(zhuǎn)實(shí)例對(duì)象 var10000 = (ReflectionDemo)var1; // 入?yún)€(gè)數(shù)校驗(yàn) if (var2.length != 2) { throw new IllegalArgumentException(); } // 入?yún)㈩?lèi)型轉(zhuǎn)換 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 { // 實(shí)例對(duì)象調(diào)用目標(biāo)方法 return var10000.targetString(var10001, var10002); } catch (Throwable var4) { throw new InvocationTargetException(var4); } } } }
反射的實(shí)現(xiàn)原理
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
相關(guān)閱讀更多精彩內(nèi)容
- /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home...
- 前段時(shí)間看了笨神的 從一起GC血案談到反射原理一本,就把Java方法的反射機(jī)制實(shí)現(xiàn)擼了一遍。 一起GC血案談到反射...
- 簡(jiǎn)書(shū) 占小狼轉(zhuǎn)載請(qǐng)注明原創(chuàng)出處,謝謝! “物有本末,事有始終。知其先后,則近道矣” 前段時(shí)間看了笨神的 從一起GC...
