Java反射

172 阅读2分钟

反射是指:在运行期间加载、探知和使用编译期间完全未知的能力,例如动态代理

反射依赖于Class类和java.lang.reflect类库,主要类型如下:

 Class、 Field、 Method、 Constructor、 Array 

其中Class类有三个特点: 

1.Class类也是类的一种,class则是关键字 

2.Class类只有一个构造函数,只有JVM能够创建实例 

3.同一个类的对象,在JVM中只有唯一一个与之对应的CLass类实例来描述(包名+类名) .class文件存了Class的所有信息,JVM启动时通过.class文件将相关的类加载到内存中


Class:

获取Class实例:

其中Class唯一的构造函数:

private Class(){}

可以看出无法使用new来获取Class实例

Class.forName() 方法

通过forName方法来获取Class实例,该方法只能获取引用类型的类类型对象

// 这种方式会使用当前的类的加载器加载,并且会将 Class 类实例初始化
Class<?> clazz = Class.forName("java.lang.String");Object.getClass() 方法

可能会抛出ClassNotFoundException,原因

  • 类加载器在类路径中没有找到该类
  • 该类已经被某个类加载器加载到 JVM 内存中,另外一个类加载器又尝试从同一个包中加载
Object.getClass()方法

Class clazz = "yif".getClass();

class语法

只需知道类名称即可:

Class clazz = Integer.class;

包装类的TYPE静态属性

对于基本类型和void都有对应的包装类,包装类中有一个静态属性TYPE,保存了该类类型,因此生成Class类实例的方法可以为:

Class clazz = Integer.TYPE;
Class clazz2 = Void.TYPE;


Field:

field提供了有关类或接口的单个属性的信息,以及对它的动态访问的能力


Method: 

Method 提供了有关类或接口的单个方法的信息,以及对它的动态访问的能力


Constructor:

Constructor 提供了有关类的构造方法的信息,以及对它的动态访问的能力。


Array:

在 Java 中数组也是一种类,Array 提供了动态创建数组和访问数组元素的静态方法。

  • getXX(Object array, int index):传入数组对象和下标索引,获取该位置的值
  • newInstance(Clazz<?> componentType, int length):传入数组类型和长度,创建数组

int x[] = new int[10];
int y[] = (int[]) Array.newInstance(int.class, 10);
System.out.println(x.length == y.length);   //结果为true


反射应用场景

动态配置:读取写好的配置文件的值,然后通过反射机制将这些值设置到配置类中