跳到主要内容

Java反射

· 阅读需 5 分钟
小猪

Java 反射(Reflection)是 Java 语言的一个特性,它可以让我们在运行时动态地获取和操作类、对象、方法、属性等信息。反射的应用场景非常广泛,比如框架开发、动态代理、注解处理等。本文将介绍 Java 反射的基本概念和用法,以及一些常见的问题和注意事项。

什么是反射?

反射是一种元编程(metaprogramming)技术,即编写能够操作其他代码的代码。在 Java 中,反射主要通过 java.lang.reflect 包中的类和接口来实现,例如 Class、Method、Field、Constructor 等。通过反射,我们可以在运行时获取类的结构信息,比如类名、父类、接口、构造器、方法、属性等;也可以创建类的实例,调用方法,修改属性值等。反射可以让我们编写更灵活和通用的代码,但也会带来一些性能开销和安全风险。

Java 反射即通过 Class 类提供的一系列方法,来访问和修改类的结构和行为。Class 类是 Java 中的一个特殊类,它可以描述任意一个类的属性、方法、构造器、接口、父类等信息。我们可以通过 Class 对象来创建类的实例,调用类的方法,修改类的字段,甚至动态生成新的类。

如何使用反射?

要使用反射,我们首先需要获取目标类的 Class 对象,它是反射的入口。有三种常用的方式可以获取 Class 对象:

  • 通过类名.class,例如 String.class
  • 通过对象的 getClass() 方法,例如 "hello".getClass()
  • 通过 Class.forName() 静态方法,例如 Class.forName("java.lang.String")

获取到 Class 对象后,我们就可以使用它的各种方法来获取和操作类的信息。例如:

  • getSuperclass():获取父类的 Class 对象
  • getInterfaces():获取实现的接口的 Class 对象数组
  • getModifiers():获取类的修饰符,例如 public、abstract 等
  • getConstructor():获取指定参数类型的构造器
  • getConstructors():获取所有公有的构造器
  • getDeclaredConstructor():获取指定参数类型的构造器,包括私有的
  • getDeclaredConstructors():获取所有声明的构造器,包括私有的
  • getMethod():获取指定名称和参数类型的公有方法
  • getMethods():获取所有公有的方法,包括继承的
  • getDeclaredMethod():获取指定名称和参数类型的方法,包括私有的
  • getDeclaredMethods():获取所有声明的方法,包括私有的
  • getField():获取指定名称的公有属性
  • getFields():获取所有公有的属性,包括继承的
  • getDeclaredField():获取指定名称的属性,包括私有的
  • getDeclaredFields():获取所有声明的属性,包括私有的

除了获取信息之外,我们还可以使用反射来创建对象、调用方法、修改属性等。例如:

  • newInstance():通过无参构造器创建对象
  • Constructor.newInstance(Object... args):通过指定参数构造器创建对象
  • Method.invoke(Object obj, Object... args):调用指定对象和参数的方法
  • Field.set(Object obj, Object value):设置指定对象和值的属性
  • Field.get(Object obj):获取指定对象的属性值

以上这些方法都会返回一个或多个 Field、Method 或 Constructor 的对象,这些对象也提供了一些方法来访问和修改它们所描述的成员。例如:

  • set(Object obj, Object value):给指定对象的字段赋值。
  • get(Object obj):获取指定对象的字段值。
  • invoke(Object obj, Object... args):调用指定对象的方法,并传入参数。
  • newInstance(Object... args):创建一个新的对象,并传入构造器参数。

需要注意的是,如果要操作私有成员,需要先调用 setAccessible(true) 方法来取消 Java 的访问检查。