美文网首页
java反射总结

java反射总结

作者: 只会写一点点代码 | 来源:发表于2019-08-27 10:12 被阅读0次

一、定义

如果让我用一句话总结一下java反射机制的话,我会说反射就是把java类中的各种成分映射成相应的
Java类。下面就从几个方面介绍一下java的反射机制,思考才会进步。

二、介绍

  • 1、java Jvm是如何将java代码进行运行的呢?

    在这里插入图片描述

    这幅丑图介绍了java虚拟机将java代码使用的一个过程。但是注意的是加载->验证->准备
    ->初始化->卸载是顺序的,按部就班的开始,但是解析和使用过程不一定按顺序执行,
    这也是为了支持Java的运行时绑定。

  • 加载和类加载:
    我们所熟悉的类加载和加载是两个不同的概念,不要混淆,加载只是类加载的一个阶段。

  • 类加载过程:(java代码其实计算机是读不懂的,需要一个翻译的过程)

    • 加载:当我们编写好java代码的时候,第一步虚拟机需要完成下述的三个过程:
      1、 java一切都是对象,虚拟机会根据类的全路径名来获取此类的一个二进制字节流;
      2、 将这个二进制流(这里我们就可以理解为代码对应的二进制)放到方法区,并且转化为运行时的数据结构;
      3、开辟对应的内存,针对这个类生成相应的Class对象,作为这个方法区的这个类的各种数据 的访问的入口。
      注意:java中对于我们常见的hotspot虚拟机,Class对象比较特殊,它虽然是对象,但是存放的
      区域为方法区,这个对象将作为程序访问方法区中这些类型数据的外部接口。
    • 连接阶段(本章不详细介绍类加载机制,所以一些知识点省略)
      验证:为了确保Class文件中的字节流包含的信息符合虚拟机规范;
      准备:正式为类变量分配内存并设置类变量的初始化值,都在方法区中进行;
      解析:是虚拟机将常量池中内的符号应用替换为直接引用的过程;
      -初始化
      就是一个按照程序员代码的逻辑去初始化类变量和其他资源。

    二、反射机制

    • 第一节我用自己的理解,解释了一下反射机制,反射就是将java中类的各种成分映射成相应
      的java类,但是这个发生的场景是什么时候呢?
      oracle的官方说法:
      Reflection enables Java code to discover information about fields,methods and constructors of loaded classes,
      and to use reflected fields, methods, and constructors to operate on their underlying counterparts,within security 
      restrictions.The API accommodates applications that need access to either the public members of a target object 
      (based on its runtime class) or the members declared by a given class. It also allows programs to suppress default 
      reflective access control.
      
      
      换句话说,就是java提供了让我们程序员可以在运行时获取程序中每个类的成员和成员信息,但是一般对象在
      编译的时候类型不是都确定下来了吗?但是java的反射机制可以动态的创建对象并且调用其方法和属性,这样
      的对象的类型在编译器是未知的。
    • Class对象
      上书介绍了类加载会将java代码放入方法区并转化为对应的数据结构。Class对象个人理解就是提供外部访问这些
      数据结构的入口,可以理解为对应的字节码。
      如何获取一个类的Class对象。
      三种方式获取(查看Class类的源码)
      Test test=new Test()
      1、对象.class--->Test.class
      2、Class对象提供的方法forName---->Class.forName("传入类的全路径名")
      3、test.getclass() obejct类中提供的方法
      三种方法,打印出的Test对象发现是相同的,我们可以得出结论相同类型的类,Jvm只有同一份字节码。
      正因为如此,instance of判断的依据,也是这样,我们还可以使用Class对象提供的方法
      public native boolean isInstance(Object obj);
      判断是否是某个类的实例。
      同理我们就可以知道我们常使用的==就是比较字节码的运算符号,利用了字节码只有一份的操作。
      
    • 反射中三个重要的类
      1、public final class Constructor<T> extends Executable
      描述这份类字节码的构造方法。
      我们知道java中new一个对象,必然调用了其构造方法,那通过反射如何生成对象呢。
      换句话说如何使用反射调用其构造方法。
      1、Class对象提供的方法:newInstance
         其实也就是调用了对象的无参构造器
      2、Constructor也提供一个方法
      public T newInstance(Object ... initargs),这个对象提供给了一个方法,首先我们就要获取这个对象
      的实例啊。找一个Class对象有没有获取Constructor的方法。
      public Constructor<?>[] getConstructors()
      public Constructor<T> getConstructor(Class<?>... parameterTypes)
      提供了两个方法,很容易理解,一个对象不止一个构造方法啊,所以java很人性化的提供了两个
      一个返回构造器的数据,一个根据你的要求返回,要什么给你什么,得到Constructor后调用方法即可。
      
      2、public final class Field extends AccessibleObject implements Member
      描述这份字节码的成员变量,得到的不是这个类实例的属性,而实这个类的属性
      据类一个Student类
      成员变量为 private String name,private String age,public String gender
      同理Class对象也提供了获取成员变量的方法。
      1、public Field[] getFields();
      2、public Field getField(String name)
      获取一个集合和根据名字获取。
      Field[] fields=stu.getFields();
      for(Field s:fields){
      System.out.println(s.toString());//这里答应只显示了gender
      }
      //注意观察因为只有gender为public,其他均为private。
      那能不能获取为private的成员变量呢,答案是可以的。我们可以设置setAccessible来进行暴力反射。
      
      3、public final class Method extends Executable
      描述这份字节码的成员方法
      同理Class对象也提供了获取Method的相应的方法
      1、public Method[] getMethods();
      2、public Method getMethod(String name, Class<?>... parameterTypes)
      第一方法返回了这个对象所有的成员方法,而第二个方法可以根据传入方法名和参数列表的方式获取。
      java还是很严谨的,这样也区分了重载的方法。
      3、public Object invoke(Object obj, Object... args)//调用方法。
      参数为两个:第一个为对象实例,第二个为传参,那如果方法为静态方法怎么办,传入null即可。
      那为什么和我们以前的不一样呢,我们不是实例.方法才调用吗。
      我这边举一个例子来解释一下。其实方法都是在类上的,实例不过是给他发一个信号而已。
      比如汽车的刹车,其实汽车的刹车是在车的身上,而司机只是给汽车一个刹车的信号而已。
      
      4、数组的反射:
      对于数组虽然是对象的加载阶段就有所不同,数组类的本身是不经过类的加载机制的,它
      是由java虚拟机直接创建,但是为什么又说数组和类加载机制又有密切的关系呢,因为数组
      类的元素类型比如Integer[],String[]等还是要靠类加载机制去加载的。
      我个人理解为每个数组只要是相同的类型,相同的维度(维度指一维,二维)是共享一份字节码的。
      这些数组都继承object[]对应的字节码。
      eg: Integer[] integers=new Integer[10];
              Integer[] integers1=new Integer[20];
              运行代码会发现返回的为true,来证明了上述的结论。
               
      

三、反射的应用

平时的业务代码中,反射的应用场景好像很少,其实反射的重要的途径就是开发框架,我们常用的
idea中你输入一个对象,直接点一下,便会出现相应的方法,我觉得这不就用到了反射吗?哈哈
但是反射在使用中还是需要注意的;
1、大量的使用反射会让代码的可读性很差;
2、反射还会消耗一定的系统资源,所以如果不需要动态的创建一个对象,还是不要使用反射;
3、反射的调用可以暴力反射,直接越过java提供的权限检查,完全破坏了java的封装性,所以知道类的全路径名,也是一件很可怕的事情。

四、总结

java的反射机制介绍完了,越发觉得接触的越多,不会的东西就越多,java生态很多知识还是一知半解,最后java的开发设计人员表示尊敬。也勉励自己需要平心静气深入研究,mybatis的反射模块的设计和编码还是很优秀和值得借鉴的,目前也准备去撸一遍。

相关文章

  • 反射之一

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • 反射之二

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • 反射之三

    总结内容源自以下文章 粗浅看java反射机制 反射机制应用实践 谈谈java反射机制 Java Reflectio...

  • Java反射

    简单总结下什么是Java反射,怎么使用。 Java反射机制 反射就是指JVM运行期,获取指定类所有的属性和方法的一...

  • Java反射使用总结

    Java反射总结 1.反射机制的定义 1.1定义 Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类...

  • java反射总结

    所用到的类 java.lang.Class java.lang.reflect.Constructor java....

  • Java反射总结

    1、Class对象的获取 Java中对象可以分为两种,一种是实例对象,一种是Class对象。Class对象是在类加...

  • Java 反射总结

    什么是反射官方有段介绍是这么说的 Reflection is commonly used by programs ...

  • Java反射总结

    Java反射总结 概述 通常在Java代码中使用一个类,需要在编译时知道类的位置。但是在某些时候,需要使用的类在编...

  • Java反射总结

    概念介绍 Java反射机制JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任...

网友评论

      本文标题:java反射总结

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