反射的實(shí)現(xiàn)原理

  • 反射的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);
                }
            }
        }
    }
    
?著作權(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ù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容