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,我們可以快速獲取類的資訊。