在 Java 中,反射允许我们在运行时检查和操作 类、接口、构造函数、方法 和字段。
Java 中有一个名为 Class
的类,它在运行时存储有关对象和类的所有信息。Class
的对象可用于执行反射。
Java 类反射
为了反射一个 Java 类,我们首先需要创建一个 Class
对象。
然后,我们可以使用该对象调用各种方法来获取有关类中存在的方法、字段和构造函数的信息。
创建 Class 对象的有三种方法
1. 使用 forName() 方法
class Dog {...}
// create object of Class
// to reflect the Dog class
Class a = Class.forName("Dog");
在这里,forName()
方法将其要反射的类的名称作为参数。
2. 使用 getClass() 方法
// create an object of Dog class
Dog d1 = new Dog();
// create an object of Class
// to reflect Dog
Class b = d1.getClass();
在这里,我们使用 Dog 类的对象来创建 Class
对象。
3. 使用 .class 扩展
// create an object of Class
// to reflect the Dog class
Class c = Dog.class;
现在我们知道了如何创建 Class
对象。我们可以使用此对象在运行时获取有关相应类的信息。
示例:Java 类反射
import java.lang.Class;
import java.lang.reflect.*;
class Animal {
}
// put this class in different Dog.java file
public class Dog extends Animal {
public void display() {
System.out.println("I am a dog.");
}
}
// put this in Main.java file
class Main {
public static void main(String[] args) {
try {
// create an object of Dog
Dog d1 = new Dog();
// create an object of Class
// using getClass()
Class obj = d1.getClass();
// get name of the class
String name = obj.getName();
System.out.println("Name: " + name);
// get the access modifier of the class
int modifier = obj.getModifiers();
// convert the access modifier to string
String mod = Modifier.toString(modifier);
System.out.println("Modifier: " + mod);
// get the superclass of Dog
Class superClass = obj.getSuperclass();
System.out.println("Superclass: " + superClass.getName());
}
catch (Exception e) {
e.printStackTrace();
}
}
}
输出
Name: Dog Modifier: public Superclass: Animal
在上面的示例中,我们创建了一个超类 Animal 和一个子类 Dog。在这里,我们尝试检查 Dog 类。
请注意以下语句:
Class obj = d1.getClass();
在这里,我们使用 getClass()
方法创建了一个 Class
的对象 obj。使用该对象,我们调用 Class
的各种方法。
- obj.getName() - 返回类的名称
- obj.getModifiers() - 返回类的访问修饰符
- obj.getSuperclass() - 返回类的超类
要了解更多关于 Class
的信息,请访问 Java Class (官方 Java 文档)。
注意:我们使用 Modifier
类将整数访问修饰符转换为 字符串。
反射字段、方法和构造函数
java.lang.reflect
包提供了可用于操作类成员的类。例如,
- Method 类 - 提供有关类中方法的信息
- Field 类 - 提供有关类中字段的信息
- Constructor 类 - 提供有关类中构造函数的信息
1. Java 方法反射
Method
类提供了各种方法,可用于获取有关类中存在的方法的信息。例如,
import java.lang.Class;
import java.lang.reflect.*;
class Dog {
// methods of the class
public void display() {
System.out.println("I am a dog.");
}
private void makeSound() {
System.out.println("Bark Bark");
}
}
class Main {
public static void main(String[] args) {
try {
// create an object of Dog
Dog d1 = new Dog();
// create an object of Class
// using getClass()
Class obj = d1.getClass();
// using object of Class to
// get all the declared methods of Dog
Method[] methods = obj.getDeclaredMethods();
// create an object of the Method class
for (Method m : methods) {
// get names of methods
System.out.println("Method Name: " + m.getName());
// get the access modifier of methods
int modifier = m.getModifiers();
System.out.println("Modifier: " + Modifier.toString(modifier));
// get the return types of method
System.out.println("Return Types: " + m.getReturnType());
System.out.println(" ");
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
输出
Method Name: display Modifier: public Return Types: void Method Name: makeSound Modifier: private Return Types: void
在上面的示例中,我们试图获取 Dog 类中存在的方法的信息。如前所述,我们首先使用 getClass()
方法创建了 Class
的对象 obj。
注意表达式:
Method[] methods = obj.getDeclaredMethod();
在这里,getDeclaredMethod()
返回类中存在的所有方法。
此外,我们还创建了 Method
类的对象 m。这里,
- m.getName() - 返回方法的名称
- m.getModifiers() - 以整数形式返回方法的访问修饰符
- m.getReturnType() - 返回方法的返回类型
Method
类还提供了各种其他方法,可用于在运行时检查方法。要了解更多,请访问 Java Method 类 (官方 Java 文档)。
2. Java 字段反射
与方法类似,我们还可以使用 Field
类的方法来检查和修改类的不同字段。例如,
import java.lang.Class;
import java.lang.reflect.*;
class Dog {
public String type;
}
class Main {
public static void main(String[] args) {
try {
// create an object of Dog
Dog d1 = new Dog();
// create an object of Class
// using getClass()
Class obj = d1.getClass();
// access and set the type field
Field field1 = obj.getField("type");
field1.set(d1, "labrador");
// get the value of the field type
String typeValue = (String) field1.get(d1);
System.out.println("Value: " + typeValue);
// get the access modifier of the field type
int mod = field1.getModifiers();
// convert the modifier to String form
String modifier1 = Modifier.toString(mod);
System.out.println("Modifier: " + modifier1);
System.out.println(" ");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
输出
Value: labrador Modifier: public
在上面的示例中,我们创建了一个名为 Dog 的类。它包含一个名为 type 的公共字段。注意语句:
Field field1 = obj.getField("type");
在这里,我们访问 Dog 类的公共字段,并将其分配给 Field
类的对象 field1。
然后,我们使用 Field
类的各种方法
- field1.set() - 设置字段的值
- field1.get() - 返回字段的值
- field1.getModifiers() - 以整数形式返回字段的值
同样,我们也可以访问和修改私有字段。但是,私有字段的反射与公共字段略有不同。例如,
import java.lang.Class;
import java.lang.reflect.*;
class Dog {
private String color;
}
class Main {
public static void main(String[] args) {
try {
// create an object of Dog
Dog d1 = new Dog();
// create an object of Class
// using getClass()
Class obj = d1.getClass();
// access the private field color
Field field1 = obj.getDeclaredField("color");
// allow modification of the private field
field1.setAccessible(true);
// set the value of color
field1.set(d1, "brown");
// get the value of field color
String colorValue = (String) field1.get(d1);
System.out.println("Value: " + colorValue);
// get the access modifier of color
int mod2 = field1.getModifiers();
// convert the access modifier to string
String modifier2 = Modifier.toString(mod2);
System.out.println("Modifier: " + modifier2);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
输出
Value: brown Modifier: private
在上面的示例中,我们创建了一个名为 Dog 的类。该类包含一个名为 color 的私有字段。注意语句。
Field field1 = obj.getDeclaredField("color");
field1.setAccessible(true);
在这里,我们正在访问 color 并将其分配给 Field
类的对象 field1。然后,我们使用 field1 来修改 color 的可访问性,并允许我们对其进行更改。
然后,我们使用 field1 对私有字段 color 执行各种操作。
要了解有关 Field 不同方法的更多信息,请访问 Java Field 类 (官方 Java 文档)。
3. Java 构造函数反射
我们还可以使用 Constructor
类提供的各种方法来检查类的不同构造函数。例如,
import java.lang.Class;
import java.lang.reflect.*;
class Dog {
// public constructor without parameter
public Dog() {
}
// private constructor with a single parameter
private Dog(int age) {
}
}
class Main {
public static void main(String[] args) {
try {
// create an object of Dog
Dog d1 = new Dog();
// create an object of Class
// using getClass()
Class obj = d1.getClass();
// get all constructors of Dog
Constructor[] constructors = obj.getDeclaredConstructors();
for (Constructor c : constructors) {
// get the name of constructors
System.out.println("Constructor Name: " + c.getName());
// get the access modifier of constructors
// convert it into string form
int modifier = c.getModifiers();
String mod = Modifier.toString(modifier);
System.out.println("Modifier: " + mod);
// get the number of parameters in constructors
System.out.println("Parameters: " + c.getParameterCount());
System.out.println("");
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
输出
Constructor Name: Dog Modifier: public Parameters: 0 Constructor Name: Dog Modifier: private Parameters: 1
在上面的示例中,我们创建了一个名为 Dog 的类。该类包含两个构造函数。
我们使用反射来查找有关类构造函数的信息。注意语句:
Constructor[] constructors = obj.getDeclaredConstructor();
在这里,我们访问 Dog 中存在的所有构造函数,并将它们分配给 Constructor
类型的数组 constructors。
然后,我们使用对象 c 来获取有关构造函数的不同信息。
- c.getName() - 返回构造函数的名称
- c.getModifiers() - 以整数形式返回构造函数的访问修饰符
- c.getParameterCount() - 返回每个构造函数中存在的参数数量
要了解有关 Constructor
类更多方法的更多信息,请访问 Constructor 类