美文网首页
反射的实现原理

反射的实现原理

作者: 5473631d8226 | 来源:发表于2018-09-08 23:16 被阅读0次
  • 反射的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);
                }
            }
        }
    }
    

相关文章

  • 反射的实现原理

    反射的demopackage com.java.reflect;import java.lang.reflect....

  • 深入理解Java虚拟机三

    一、Java反射的实现原理 1.反射调用的实现 反射是Java语言中一个相当重要的特性,它允许正在运行的Ja...

  • Java反射实现原理

    Java反射应用十分广泛,例如spring的核心功能控制反转IOC就是通过反射来实现的,本文主要研究一下发射方法调...

  • 漫反射和高光反射在Surf Shader中的原理

    漫反射的实现原理: dot(入射光线,法线)*灯光颜色*纹理颜色*衰减度 高光反射 phone 模式 dot...

  • 无处不在的反射

    本文不讲反射的具体实现。 1.反射的原理 - class对象 11)class对象概述 编译阶段,编译器将java...

  • 反射机制原理的深度理解2017-12-26

    首先我们编写person.java文件如下: 然后创建测试反射机制的类 原理解析: 要理解反射机制的实现过程,首先...

  • 深入 ProtoBuf - 反射原理解析

    在介绍了 ProtoBuf 序列化原理之后,本文介绍 ProtoBuf 的反射技术原理。 反射技术简介 对于反射大...

  • 注解

    注解实现原理 底层使用反射实现。申明注解类需要加 @interface 注解类里只支持基本类型、String以及枚...

  • 华与华方法(8)传播第一原理

    传播三大原理: 第一原理:刺激反射原理 第二原理:播传原理 第三原理:信号能量原理。 一、刺激反射原理 所有传播都...

  • Swift-进阶:Mirror源码解析

    本文主要是分析Mirror的底层实现,以及根据Mirror底层原理仿写其结构的实现 在Swift-进阶:反射Mir...

网友评论

      本文标题:反射的实现原理

      本文链接:https://www.haomeiwen.com/subject/ddtrgftx.html