美文网首页JVM
JVM05 JVM是如何实现反射的?

JVM05 JVM是如何实现反射的?

作者: 夜阑人儿未静 | 来源:发表于2018-12-19 15:11 被阅读13次

    什么是Java的反射机制?
    java的反射机制是在运行状态中,对于任意一个类(Class)都能知道他的属性(Field)和方法(Method),对于任意一个对象都能够调用它的方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。它允许正在运行的java程序观测甚至是修改程序的动态行为。

    反射的实现方式有哪些?
    1、通过Class.forName()方法加载字符串

    Class<?> clazz = Class.forName("java.lang.String")
    

    2、通过类名调用class属性得到该类的Class对象

     Class<?> clazz = String.class
    

    3、调用实例的getClass()方法

     Class<?> clazz = date.getClass()
    

    4、如果是基本类型的包装类,则可以通过调用包装类的Type属性来获得该包装类的Class对象

    反射调用是怎么实现的?
    查阅 Method.invoke 的源代码发现,它实际上委派给 MethodAccessor 来处理。

    public final class Method extends Executable {
      ...
      public Object invoke(Object obj, Object... args) throws ... {
        ... // 权限检查
        MethodAccessor ma = methodAccessor;
        if (ma == null) {
          ma = acquireMethodAccessor();
        }
        return ma.invoke(obj, args);
      }
    }
    

    MethodAccessor 是一个接口,它有两个实现:一个通过本地方法来实现反射调用,另一个使用了委派模式(委派实现)。
    在默认情况下,方法的反射调用为委派实现,委派给本地实现来进行方法调用。在调用超过 15 次之后,委派实现便会将委派对象切换至动态实现。这个动态实现的字节码是自动生成的,它将直接使用 invoke 指令来调用目标方法。

    反射调用带来哪些性能开销?
    1、接口的通用性,java的invoke方法是传object和object[]数组的。基本参数类型需要装箱和拆箱,产生大量额外的对象和内存开销,频繁促发GC。
    2、编译器难以对动态调用的代码提前做优化比如方法内联。
    3、反射需要按名检索类和方法,有一定的时间开销。

    反射在java中的应用有哪些?
    1、java集成开发环境,每当我们敲入点号时,IDE便会根据点号前的内容,动态展示可以访问的字段和方法。
    2、java调试器,它能够在调试过程中枚举某一对象所有字段的值。
    3、web开发中,我们经常接触到各种配置的通用框架。为保证框架的可扩展性,他往往借助java的反射机制。例如Spring框架的依赖反转(IOC)便是依赖于反射机制。
    4、AOP拦截获取方法信息。典型的例子:Spring缓存@Cacheable的key生成策略

    相关文章

      网友评论

        本文标题:JVM05 JVM是如何实现反射的?

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