Java 中的 reflection 是什么

Mohammad Irfan 2023年10月12日
  1. 类对象
  2. Java 中的类 forName() 方法
  3. Java 中的类 getClass() 方法
  4. Java 中有用的 reflection 方法
  5. 对方法进行 reflection 的有用方法
  6. 对字段进行 reflection 的有用方法
  7. 结论
Java 中的 reflection 是什么

本教程介绍 reflection 以及如何在 Java 中使用它。Java 有一个 reflection API 特性,它允许我们检查和修改类、接口等。

在本教程中,我们将了解什么是 reflection API 及其用途。Java 中的 reflection 允许我们在运行时观察和更改类、接口、构造函数、方法和字段,即使我们在编译时不知道类名。

创建新对象、调用方法和获取/设置字段值都可以通过 reflection 完成。让我们通过一些例子来理解。

我们首先需要导入以下包来使用 reflection API。

java.lang.reflect.*

它导入 reflection API 中包含的所有类。

类对象

导入包后,我们需要创建一个类对象来使用 reflection API 方法。

类存在于 Java 中,因为它在运行时跟踪有关对象和类的所有数据。reflection 可以在 Class 对象上执行。

可以通过三种方式创建类对象。我们将逐一研究每种方法。

但在此之前,让我们创建一个将在本教程中使用的类。

class Furniture {
  public String name;
  private int price;

  public Furniture(String name, int price) {
    this.name = name;
    this.price = price;
  }

  public void update_price(int up_price) {
    this.price = up_price;
  }

  private float cal_discount(int discount) {
    float discounted_price = (1 - discount / 100) * this.price;
    return discounted_price;
  }
}

现在,让我们创建家具类的 Class 对象。

Java 中的类 forName() 方法

Class 类提供了一个方法 forName() 来加载对象。

要使用此方法,我们必须知道要反映的类的名称。然后我们将类名作为参数传递给 forName() 方法。

看下面的代码:

Class class
= Class.forName("Furniture");

如果 Java 找不到该类,此方法将引发 ClassNotFoundException

Java 中的类 getClass() 方法

我们在要反映的类的对象上调用此方法。此方法返回对象的类。

看下面的代码:

Furniture furniture = new Furniture("Chair", 8565);
Class f = furniture.getClass();

我们还可以使用 .class 特性来获取类对象以进行 reflection。

// create a class object to relect on furniture
Class f = Furniture.class;

Java 中有用的 reflection 方法

类对象有以下三个方法,可以用来对类进行 reflection。

  • getName():此方法返回类的名称。
  • getModifiers():此方法返回一个表示类访问修饰符的整数。然后我们可以使用 Modifier.toString() 方法将此整数转换为字符串。
  • getSuperclass():此方法返回方法的超类。

让我们看一个例子来理解这些方法。

import java.lang.reflect.Modifier;
public class SimpleTesting {
  public static void main(String[] args) {
    // create an object of furniture class
    Furniture furniture = new Furniture("Chair", 8565);
    // create a class object to relect on furniture
    Class f = furniture.getClass();

    // get the name of the class
    String class_name = f.getName();
    System.out.println("The class name is " + class_name);

    // get the class modifier
    int f_modifier = f.getModifiers();
    String f_mod = Modifier.toString(f_modifier);
    System.out.println("The modifier of the class is " + f_mod);

    // get the superclass of the class
    Class f_superclass = f.getSuperclass();
    System.out.println("The Superclass of the class is " + f_superclass.getName());
  }
}

输出:

The class name is Furniture
The modifier of the class is
The Superclass of the class is java.lang.Object

对方法进行 reflection 的有用方法

Java 提供了一个名为 Method 的类,它在 reflection 期间处理方法。

一个名为 getDeclaredMethods() 的方法返回一个包含类中定义的所有方法的数组。返回的方法属于类 Method。

Method 类包含几个用于检索有关类中方法的信息的方法。我们将使用方法类的以下方法:

  • Method.getName():此方法返回方法的名称。
  • Method.getModifiers():此方法返回一个整数,表示该方法的访问修饰符。
  • Method.getReturnType():此方法返回方法的返回类型。

让我们看一个例子来理解这些方法。

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class SimpleTesting {
  public static void main(String[] args) {
    // create an object of furniture class
    Furniture furniture = new Furniture("Chair", 8565);
    // create a class object to relect on furniture
    Class f = furniture.getClass();

    // using object f of Class to
    // get all the declared methods of Furniture
    Method[] f_methods = f.getDeclaredMethods();

    for (Method f_method : f_methods) {
      // get the name of the method
      System.out.println("Method Name: " + f_method.getName());

      // get the access modifier of methods
      int f_modifier = f_method.getModifiers();
      System.out.println("Modifier: " + Modifier.toString(f_modifier));

      // get the return type of the methods
      System.out.println("Return Types: " + f_method.getReturnType());
      System.out.println(" ");
    }
  }
}

输出:

Method Name: update_price
Modifier: public
Return Types: void

Method Name: cal_discount
Modifier: private
Return Types: float

在上面的例子中,我们试图了解家具类中定义的方法。我们首先必须使用 getClass() 方法创建一个 Class 对象。

对字段进行 reflection 的有用方法

我们还可以使用 Field 类的方法检查和更改类的不同字段。有一种方法叫。

class.getField
(<field name>)

此方法接受一个参数:我们要访问的字段的名称,并返回所传递字段的 Field 对象。然后我们可以使用 Field 类对象来调用各种方法。

我们将使用 Field 类的以下方法。

  • Field.set():此方法设置字段的值。
  • Field.get():此方法返回存储在字段中的值。
  • Field.getModifier():此方法返回一个整数,表示字段的访问修饰符。

让我们看一个例子来理解这些方法。

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class SimpleTesting {
  public static void main(String[] args) throws Exception {
    // create object of the furniture class
    Furniture furniture = new Furniture("Chair", 8565);
    // create a class object to relect on furniture
    Class f = furniture.getClass();

    // using object f of Class to
    // acces the name field of Furniture
    Field f_name = f.getField("name");

    // get the value of the field
    String f_name_value = (String) f_name.get(furniture);
    System.out.println("Field value before changing: " + f_name_value);

    // changing the field value
    f_name.set(furniture, "Table");

    // get the value of the field
    f_name_value = (String) f_name.get(furniture);
    System.out.println("Field value after changing: " + f_name_value);

    // get the access modifier
    int f_name_mod = f_name.getModifiers();

    // convert the access modifier to String form
    String f_name_modifier = Modifier.toString(f_name_mod);
    System.out.println("Modifier: " + f_name_modifier);
    System.out.println(" ");
  }
}

输出:

Field value before changing: Chair
Field value after changing: Table
Modifier: public

访问私有字段是类似的,除了我们必须使用方法 setAccessible() 并传递 true 作为其参数来修改私有字段的可访问性。

看下面的示例代码;我们正在尝试访问和修改家具类的私有字段价格。

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class SimpleTesting {
  public static void main(String[] args) throws Exception {
    // create object of the furniture class
    Furniture furniture = new Furniture("Chair", 8565);
    // create a class object to reflect on furniture
    Class f = furniture.getClass();

    // using object f of Class to
    // access the price field of Furniture
    Field f_price = f.getDeclaredField("price");

    // modifying the accessibility
    f_price.setAccessible(true);

    // get the value of the field
    int f_price_value = (Integer) f_price.get(furniture);
    System.out.println("Field value before changing: " + f_price_value);

    // changing the field value
    f_price.set(furniture, 453);

    // get the value of the field
    f_price_value = (Integer) f_price.get(furniture);
    System.out.println("Field value after changing: " + f_price_value);

    // get the access modifier
    int f_price_mod = f_price.getModifiers();

    // convert the access modifier to String form
    String f_price_modifier = Modifier.toString(f_price_mod);
    System.out.println("Modifier: " + f_price_modifier);
    System.out.println(" ");
  }
}

输出:

Field value before changing: 8565
Field value after changing: 453
Modifier: private

结论

看完这篇文章,我们对 Java 中的 reflection 有了足够的了解。

我们还研究了 Java 中用于 reflection 的类和方法。我们学习了如何获取类的名称及其方法和字段。

使用 reflection API,我们可以快速获取类的信息。