Java 反射

静态代码 vs 动态代码

  1. 静态代码
    通常,在编写程序时,在编写和编译阶段,所有类名、方法名和变量名都是静态已知的:
1
Foo myObject = new Foo();

如果Foo类不存在,java编译器将会返回错误。
2. 动态代码
我们也可以创建没有Foo静态符号名名的对象,这有时称为动态编码:

1
Object myObject = Class.forName("Foo").getConstructor().newInstance();

这种代码即使Foo这个类不存在,编译器也不会报错而只会在运行阶段报错,抛出ClassNotFoundException的错误

反射

反射是程序在运行时检查其自身结构的能力。

反射API

每个类、接口还有类型(包括基本类型)都都有对应的Class对象来获取他们的元数据。Class对象是反射API的主要入口

获取一个Class对象

  1. 调用getClass()方法
    1
    Class<?> c = "Hello World".getClass();
  2. .class来获取类文字
    1
    Class<String> c = String.class;
  3. Class.forName()动态获取类对象
    1
    Class<String> c = Class.forName("java.lang.String");

获取Method对象

使用getMethod()方法可以获取一个Class对象的方法,用invoke()方法可以调用获取的方法。

动态代理

动态代理是一个实现运行时指定接口列表的类。

注解(Annotation)

注解是提供有关程序的额外元数据的一种方式。注释仅提供元数据,他们对被注释代码的执行没有其他影响

那么我们什么时候需要注解呢?

  1. 为Java编译器增加额外信息来检查错误, 例如@Override注解。
  2. 注解元数据可以在运行时保留,工具可以使用反射发现他们,并根据注释元数据做出决策或执行操作。
  3. 注释可以为代码生成工具或其他工具提供编译时的信息