美文网首页
JVM的反射实现

JVM的反射实现

作者: 是茜茜呀 | 来源:发表于2018-09-04 13:13 被阅读0次

java的反射机制

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

在java中实现反射最重要的一步也就是第一步是获得Class对象,得到该对象后可通过该对象调用相应的方法获取该类中的属性方法,以及调用该类中的方法。

Java中反射有如下几种实现方式:

1、通过Class.forName()方法加载字符串,就可以得到该字符串做代表的Class对象。

如:Class<?> clazz = Class.forName("java.lang.String")就可以得到String类的Class对象。值得注意的是,字符串必须是类的全名,即包名+类名。

下边的代码是Struts配置文件struts.xml中的一个action的配置。

<action name="registe" class="cn.com.test.struts2.RegisteAction">

  <result>/registeResult.jsp</result>

  <result name="input">/registe2.jsp</result>

</action>

服务器就是通过class属性给出的类的全命名class="cn.com.test.struts2.RegisteAction"的字符串来得到对象的,就是反射机制RegisteAction的。然后再去调用这个类中execute()方法。

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

Class<?> clazz = String.class也可以得到String类的Class对象。

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

如:Date date = new Date();

      Class<?> clazz = date.getClass();

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

如:Class<?> clazz = Integer.TYPE;

我们可以通过Class对象枚举该类中的所有方法,还可以通过Method.setAccessible(位于java.lang.reflect包,该方法继承自AccessibleObject)绕过java语言的访问权限,在私有方法所在类之外的地方调用该方法。

反射在java中的应用

1、java集成开发环境,每当我们敲入点号时,IDE便会根据点号前的内容,动态展示可以访问的字段和方法。

2、java调试器,它能够在调试过程中枚举某一对象所有字段的值。

3、web开发中,我们经常接触到各种配置的通用框架。为保证框架的可扩展性,他往往借助java的反射机制。例如Spring框架的依赖反转(IOC)便是依赖于反射机制。

反射调用的实现Mehod.invoke

1 public Object invoke(Object obj, Object... args)

2        throws IllegalAccessException, IllegalArgumentException,

3            InvocationTargetException

4    {

5        if (!override) {

6            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {

7                Class<?> caller = Reflection.getCallerClass();

8                checkAccess(caller, clazz, obj, modifiers);

9            }

10        }

11        MethodAccessor ma = methodAccessor;            // read volatile

12        if (ma == null) {

13            ma = acquireMethodAccessor();

14        }

15        return ma.invoke(obj, args);

16    }

你会发现,它实际上是委派给 MethodAccessor 来处理。MethodAccessor  是一个接口,它有两个实现:一个通过本地方法来实现反射调用,另一个使用了委派模式(这里我们称委派实现)。

每个 Method 实例的第一次反射调用都会生成一个委派实现,他所委派的具体实现便是一个本地实现。当进入JVM内部后,我们便拥有了Mehod 实例所指向方法的具体地址。这时反射调用无非就是将传入的参数准备好,然后调用进入目标方法。

反射调用先是调用了Method.invoke, 然后进入委派实现(DelegatingMethodAccessorImpl),再进入本地实现(NativeMethodAccessorImpl),最后到达目标方法。

调用了Method.invoke之后,先进行访问权限检查,再获取MethodAccessor对象,并调用MethodAccessor.invoke方法。MethodAccessor被同名Method所共享,由ReflectionFactory创建。创建机制采用一种名为inflation的方式:如果该方法的调用<=15,会创建本地实现,他的实现就是直接调用native方法实现反射,如果该方法的累计调用次数>15,会创建由字节码组装而成的MethodAccessorImpl。(是否采用inflation机制和15这个数字可以在jvm参数中调整)。

性能

通过JNI(java本地接口)调用native方法初始化更快,但是对优化有阻碍作用。随着调用次数的增多,使用动态实现可以直接以java调用的方式来实现反射,发挥了java即时编译的优化作用。

java反射调用效率慢的原因:

1、接口的通用性,java的invoke方法是传object和object[]数组的。基本参数类型需要装箱和拆箱,产生大量额外的对象和内存开销,频繁促发GC。

2、编译器难以对动态调用的代码提前做优化比如方法内联。

3、反射需要按名检索类和方法,有一定的时间开销。

相关文章

  • JVM的反射实现

    java的反射机制 java的反射机制是在运行状态中,对于任意一个类(Class)都能知道他的属性(Field)和...

  • JVM的反射调用实现

    如何执行反射调用 Java的反射调用是通过java.lang.reflect.Method的invoke调用执行,...

  • Java反射在JVM的实现

    The implementation of Java reflection in JVM 本文目录 什么是Java...

  • Class对象的一些概念

    最近在写动态代理的demo,反射是动态代理的核心实现,而反射是通过jvm中的class对象在运行期动态调用任意一个...

  • JVM05 JVM是如何实现反射的?

    什么是Java的反射机制?java的反射机制是在运行状态中,对于任意一个类(Class)都能知道他的属性(Fiel...

  • JVM深度剖析:JVM是如何实现反射的?

    反射是 Java 语言中一个相当重要的特性,它允许正在运行的 Java 程序观测,甚至是修改程序的动态行为。 举例...

  • JVM是如何实现Java反射的?

    Java的反射应用场景非常多,例如IDE在做联想时,Spring的IoC容器等等。通过反射,我们可以做一些平时做不...

  • JVM中是如何实现反射的

    前言1: 反射常用的API介绍: 获取class对象 调用静态方法Class.forName来获取 调用对象的ge...

  • 07 JVM 是如何实现反射的

    Java 中的反射 反射是 Java 语言的一个相当重要的特性,它允许正在运行的 Java 程序观测,甚至是修改程...

  • Java反射详解

    一、什么是反射? “反射(Reflection)能够让运行于JVM中的程序检测和修改运行时的行为。反射用于在运行时...

网友评论

      本文标题:JVM的反射实现

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