Java 反射机制

前言

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

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

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

1、类对象

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

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

    1
    2
    3
    4
    5
    6
    String className = "charactor.Hero";        // 包名.类名
    Class pClass1 = Class.forName(className);

    Class pClass2 = Hero.class;

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

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

2、创建对象

  • 通过反射机制创建一个对象与传统的通过 new 来获取对象的方式不同,反射机制,会先拿到 “类对象”,然后通过类对象获取 “构造器对象”。再通过构造器对象创建一个对象。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    import java.lang.reflect.Constructor;
    import charactor.Hero;

    public class TestReflection {
    public static void main(String[] args) {

    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
    Hero h = new Hero();

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

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

4、方法

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

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

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