Java 反射机制

前言

  • 反射用于解析注解中的信息。

  • 反射非常强大,但是学习了之后,会不知道该如何使用,反而觉得还不如直接调用方法来的直接和方便。

  • 通常来说,需要在学习了 Spring 的依赖注入,反转控制之后,才会对反射有更好的理解。

  • Java 反射

  • 反射机制 快速入门

1、获取类对象

  • 所有的类,都存在一个类对象,这个类对象用于提供类本身的信息,描述这种类有几种构造方法,有多少属性,有哪些普通方法。

  • 获取类对象有 3 种方式

    • Class.forName
    • Hero.class
    • new Hero().getClass()
  • 在一个JVM中,一种类,只会有一个类对象存在。所以以上三种方式取出来的类对象,都是一样的。

  • 准确的讲是一个 ClassLoader 下,一种类,只会有一个类对象存在。通常一个 JVM 下,只会有一个 ClassLoader。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    String className = "charactor.Hero";                        // 包名.类名
    try {
    Class pClass1 = Class.forName(className); // 获取类对象

    Class pClass2 = Hero.class; // 获取类对象

    Class pClass3 = new Hero().getClass(); // 获取类对象
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    }
  • 获取类对象的时候,会导致类属性被初始化。

    • 无论什么途径获取类对象,都会导致静态属性被初始化,而且只会执行一次。
    • 除了直接使用 Class c = Hero.class 这种方式,这种方式不会导致静态属性被初始化。

2、反射创建对象

  • 与传统的通过 new 来获取对象的方式不同。

  • 反射机制,会先拿到 “类对象”,然后通过类对象获取 “构造器对象”。

  • 再通过构造器对象创建一个对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import java.lang.reflect.Constructor;
    import charactor.Hero;

    try {
    String className = "charactor.Hero";
    Class pClass = Class.forName(className); // 获取类对象
    Constructor c = pClass.getConstructor(); // 获取构造器对象
    Hero h = (Hero) c.newInstance(); // 通过构造器 创建一个对象

    h.name = "gareen";
    System.out.println(h2);
    } catch (Exception e) {
    e.printStackTrace();
    }

3、访问属性

  • 通过反射机制修改对象的属性

    1
    2
    3
    4
    5
    6
    Hero h = new Hero();

    Class pClass = h.getClass(); // 获取类对象

    Field field = pClass.getDeclaredField("name"); // 获取类 Hero 的名字叫做 name 的字段
    field.set(h, "teemo"); // 修改这个字段的值
  • getField 和 getDeclaredField 的区别

    • 这两个方法都是用于获取字段。
    • getField 只能获取 public 的,包括从父类继承来的字段。
    • getDeclaredField 可以获取本类所有的字段,包括 private 的,但是不能获取继承来的字段。
    • 只能获取到 private 的字段,但并不能访问该 private 字段的值,除非加上 setAccessible(true)

4、调用方法

  • 通过反射机制,调用一个对象的方法

    1
    2
    3
    4
    5
    6
    Hero h = new Hero();

    Class pClass = h.getClass(); // 获取类对象

    Method method = pClass.getMethod("setName", String.class); // 获取这个名字叫做 setName,参数类型是 String 的方法
    method.invoke(h, "盖伦"); // 对 h 对象,调用这个方法
文章目录
  1. 1. 前言
  2. 2. 1、获取类对象
  3. 3. 2、反射创建对象
  4. 4. 3、访问属性
  5. 5. 4、调用方法
隐藏目录