Java 例付きリフレクション API チュートリアル

⚡ スマートサマリー

Java Reflection API は、実行時にクラスのフィールド、メソッド、コンストラクタなどの機能を分析および変更します。このリソースでは、java.lang.reflect パッケージ、java.lang.Class の主要なメソッド、およびクラス、変数、メソッド、コンストラクタのメタデータを読み取る 4 つの例について説明します。

  • 🔍 定義: リフレクションは、実行時にクラスとそのメンバー(プライベートなメンバーも含む)を検査および変更します。
  • 📦 Reflectパッケージ: フィールド、メソッド、コンストラクタ、および修飾子クラスは、メンバーに関する宣言的な情報を収集します。
  • 🏷️ クラスメソッド: getName()、getSuperclass()、getInterfaces()、およびgetModifiers()は、コアクラスのメタデータを返します。
  • 🧪 実用的な例: 4つのプログラムtract クラス、変数、メソッド、コンストラクタのメタデータ。
  • ⚠️ ホテルからのお願い リフレクションはプライベートメンバーにアクセスできるため、処理速度が遅くなります。したがって、最終手段として使用してください。

Java リフレクションAPIチュートリアル

反射とは何か Java?

Java リフレクションとは、実行時にクラスのすべての機能を分析および変更するプロセスです。リフレクション API は Java 実行時にクラスとそのメンバー(フィールド、メソッド、コンストラクタなど)を操作するために使用されます。

Reflection API の利点の 1 つは、 Java それは、クラスのプライベートメンバーも操作できるということです。

java.lang.reflect パッケージは、リフレクションを実装するための多くのクラスを提供します。java.lang.Class クラスのメソッドは、特定のクラスの完全なメタデータを取得するために使用されます。

java.lang.reflect パッケージのクラス

以下はのリストです さまざまな Java クラス リフレクションを実装するには、java.lang.reflect パッケージを使用します。

  • フィールド: このクラスは、変数のデータ型、アクセス修飾子、名前、値などの宣言的な情報を収集するために使用されます。
  • 方法: このクラスは、メソッドのアクセス修飾子、戻り値の型、名前、パラメータの型、例外の型などの宣言的な情報を収集するために使用されます。
  • コンストラクタ: このクラスは、コンストラクタのアクセス修飾子、名前、パラメータの型などの宣言的な情報を収集するために使用されます。
  • 修飾子: このクラスは、特定のアクセス修飾子に関する情報を収集するために使用されます。

java.lang.Classで使用されるメソッド

  • public String getName(): クラス名を返します。
  • public Class getSuperclass(): スーパークラスへの参照を返します。
  • public Class[] getInterfaces(): 指定されたクラスによって実装されるインターフェースの配列を返します。
  • public int getModifiers(): 指定されたクラスの修飾子を表す整数値を返します。この値は、指定されたクラスのアクセス指定子を返す「public static String toString(int i)」メソッドのパラメータとして渡す必要があります。

クラスに関する完全な情報を取得する方法

に関する情報を取得するには variablesクラスのメソッドやコンストラクタを使用するには、クラスのオブジェクトを作成する必要があります。次の例は、「Class」クラスのオブジェクトを作成するさまざまな方法を示しています。

java.lang.Classで使用されるメソッド

public class Guru99ClassObjectCreation {
    public static void main(String[] args) throws ClassNotFoundException {
        // 1 - By using Class.forName() method
        Class c1 = Class.forName("Guru99ClassObjectCreation");
        // 2 - By using getClass() method
        Guru99ClassObjectCreation guru99Obj = new Guru99ClassObjectCreation();
        Class c2 = guru99Obj.getClass();
        // 3 - By using .class
        Class c3 = Guru99ClassObjectCreation.class;
    }
}

例1:クラスのメタデータを取得する方法

次の例は、クラスのクラス名、スーパークラス名、実装されているインターフェース、アクセス修飾子などのメタデータを取得する方法を示しています。

下記のクラスのメタデータを取得します。 Guru99Base.class:

クラスのメタデータを取得する

import java.io.Serializable;
public abstract class Guru99Base implements Serializable, Cloneable {
}
  1. クラス名は: Guru99ベース
  2. アクセス修飾子は public と abs です。tract
  3. シリアル化可能およびクローン化可能なインターフェイスが実装されています。
  4. 明示的にクラスを継承していないため、そのスーパークラスは java.lang.Object です。

以下のクラスはメタデータを取得します Guru99Base.class を出力してください。

クラスのメタデータを取得する

import java.lang.reflect.Modifier;
public class Guru99GetclassMetaData {
    public static void main(String[] args) throws ClassNotFoundException {
        // Create Class object for Guru99Base.class
        Class<Guru99Base> guru99ClassObj = Guru99Base.class;

        // Print name of the class
        System.out.println("Name of the class is : " + guru99ClassObj.getName());

        // Print super class name
        System.out.println("Name of the super class is : " + guru99ClassObj.getSuperclass().getName());

        // Get the list of implemented interfaces using getInterfaces() method
        Class[] guru99InterfaceList = guru99ClassObj.getInterfaces();

        // Print the implemented interfaces using a for-each loop
        System.out.print("Implemented interfaces are : ");
        for (Class guru99class1 : guru99InterfaceList) {
            System.out.print(guru99class1.getName() + " ");
        }
        System.out.println();

        // Get access modifiers using getModifiers() and Modifier.toString()
        int guru99AccessModifier = guru99ClassObj.getModifiers();
        System.out.println("Access modifiers of the class are : " + Modifier.toString(guru99AccessModifier));
    }
}
  1. getName() メソッドを使用してクラス名を出力します。
  2. getSuperclass().getName() メソッドを使用して、スーパークラスの名前を出力します。
  3. 実装されているインターフェースの名前を表示します。
  4. クラスで使用されているアクセス修飾子を出力します。

クラスのメタデータを取得する

クラスのメタデータを取得する

例2:変数のメタデータを取得する方法

以下の例は、変数のメタデータを取得する方法を示しています。

ここでは、クラスを作成します。 Guru99VariableMetaData.class にはいくつかの変数が含まれています。

package guru;
public class Guru99VariableMetaData {
    public static int guru99IntVar1 = 1111;
    static int guru99IntVar2 = 2222;
    static String guru99StringVar1 = "guru99.com";
    static String guru99StringVar2 = "Learning Reflection API";
}

上記のクラスの変数に関するメタデータを取得する手順は次のとおりです。

  1. 上記のクラスのクラスオブジェクトを作成します。 Guru99VariableMetaData.class、以下参照:
    Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. メタデータをフィールド配列の形式で取得するには、 getFields() or getDeclaredFields() 以下のような方法:
    Field[] guru99Field1 = guru99ClassObjVar.getFields();
    Field[] guru99Field2 = guru99ClassObjVar.getDeclaredFields();

その getFields() このメソッドは、指定されたクラスおよびそのスーパークラスのパブリック変数のメタデータを返します。

その getDeclaredFields() このメソッドは、指定されたクラスのすべての変数のメタデータのみを返します。

  1. 「public String getName()」メソッドを使用して変数名を取得します。
  2. 「public Class getType()」メソッドを使用して、変数のデータ型を取得します。
  3. 「public xxx get(Field)」メソッドを使用して変数の値を取得します。ここで、xxxはバイト型、ショート型、または取得したい任意の型の値になります。
  4. getModifiers() メソッドと Modifier.toString(int i) メソッドを使用して、変数のアクセス修飾子を取得します。

ここでは、クラス内に存在する変数のメタデータを取得するクラスを作成します。 Guru99VariableMetaData.class:

変数のメタデータを取得する

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

public class Guru99VariableMetaDataTest {
    public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
        // Create Class object for Guru99VariableMetaData.class
        Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();
        Class guru99ClassObjVar = guru99ClassVar.getClass();

        // Get the metadata of all the fields of the class
        Field[] guru99Field1 = guru99ClassObjVar.getDeclaredFields();

        // Print name, data types, access modifiers and values of the variables
        for (Field field : guru99Field1) {
            System.out.println("Variable name : " + field.getName());
            System.out.println("Datatype of the variable : " + field.getType());

            int guru99AccessModifiers = field.getModifiers();
            System.out.println("Access Modifiers of the variable : " + Modifier.toString(guru99AccessModifiers));
            System.out.println("Value of the variable : " + field.get(guru99ClassVar));
            System.out.println();
        }
    }
}
  1. クラスオブジェクトを作成しました Guru99VariableMetaData.class。
  2. 変数のすべてのメタデータをフィールド配列に格納しました。
  3. クラス内のすべての変数名を出力しました Guru99VariableMetaData.class。
  4. クラス内のすべての変数のデータ型を出力しました。
  5. クラス内の変数のアクセス修飾子をすべて出力しました。
  6. クラス内のすべての変数の値を表示しました。

メソッドのメタデータを取得する

メソッドのメタデータを取得する

例3:メソッドのメタデータを取得する方法

以下の例は、メソッドのメタデータを取得する方法を示しています。

ここでは、クラスを作成します。 Guru99MethodMetaData.class にはいくつかのメソッドがあります。

メソッドのメタデータを取得する

package guru;
import java.sql.SQLException;
public class Guru99MethodMetaData {

    public void guru99Add(int firstElement, int secondElement, String result)
    throws ClassNotFoundException, ClassCastException {
        System.out.println("Demo method for Reflection API");
    }
    public String guru99Search(String searchString)
    throws ArithmeticException, InterruptedException {
        System.out.println("Demo method for Reflection API");
        return null;
    }
    public void guru99Delete(String deleteString)
    throws SQLException {
        System.out.println("Demo method for Reflection API");
    }
}

上記クラスのメソッドに関するメタデータを取得する手順:

  1. 上記のクラスのクラスオブジェクトを作成します。 Guru99MethodMetaData.class は以下のとおりです。
    Guru99MethodMetaData guru99ClassVar = new Guru99MethodMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. getMethods() メソッドと getDeclaredMethods() メソッドを使用して、Method 配列内のメソッド情報を取得します。手順は以下のとおりです。
    Method[] guru99Method1 = guru99ClassObjVar.getMethods();
    Method[] guru99Method2 = guru99ClassObjVar.getDeclaredMethods();

    その getメソッド() このメソッドは、指定されたクラスおよびそのスーパークラスのパブリックメソッドのメタデータを返します。 getDeclaredMethods() このメソッドは、指定されたクラスのすべてのメソッドのメタデータのみを返します。

  3. メソッドの名前を取得するには、 getName() 方法。
  4. メソッドの戻り値の型を取得するには、 getReturnType() 方法。
  5. メソッドのアクセス修飾子を取得するには、 getModifiers() (NAIST) と Modifier.toString(int i) 方法。
  6. メソッドパラメータの型を取得するには、 getParameterTypes() クラス配列を返すメソッド。
  7. スローされた例外を取得するには、 getExceptionTypes() クラス配列を返すメソッド。

ここでは、クラスに存在するメソッドのメタデータを取得するクラスを作成します。 Guru99MethodMetaData.class:

メソッドのメタデータを取得する

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

public class Guru99MethodMetaDataTest {

    public static void main(String[] args) {
        // Create Class object for Guru99MethodMetaData.class
        Class guru99ClassObj = Guru99MethodMetaData.class;

        // Get the metadata of all the methods using getDeclaredMethods()
        Method[] guru99Methods = guru99ClassObj.getDeclaredMethods();

        for (Method method : guru99Methods) {
            System.out.println("Name of the method : " + method.getName());
            System.out.println("Return type of the method : " + method.getReturnType());

            int guru99ModifierList = method.getModifiers();
            System.out.println("Method access modifiers : " + Modifier.toString(guru99ModifierList));

            Class[] guru99ParamList = method.getParameterTypes();
            System.out.print("Method parameter types : ");
            for (Class class1 : guru99ParamList) {
                System.out.print(class1.getName() + " ");
            }
            System.out.println();

            Class[] guru99ExceptionList = method.getExceptionTypes();
            System.out.print("Exception thrown by method : ");
            for (Class class1 : guru99ExceptionList) {
                System.out.print(class1.getName() + " ");
            }
            System.out.println();
        }
    }
}
  1. クラスオブジェクトを作成しました Guru99MethodMetaData.class。
  2. メソッド配列に、すべてのメソッドのメタデータを取得しました。
  3. クラスに存在するすべてのメソッド名を出力しました。
  4. クラス内のメソッドの戻り値の型を出力しました。
  5. クラス内のメソッドのアクセス修飾子をすべて出力しました。
  6. メソッドのパラメータ型を出力しました。
  7. メソッドによってスローされた例外を出力しました。

メソッドのメタデータを取得する

メソッドのメタデータを取得する

例4:コンストラクタのメタデータを取得する方法

以下の例は、コンストラクタのメタデータを取得する方法を示しています。

ここでは、クラスを作成します。 Guru99Constructor.class には、異なるコンストラクタがあります。

コンストラクターのメタデータを取得する

package guru;

import java.rmi.RemoteException;
import java.sql.SQLException;

public class Guru99Constructor {

    public Guru99Constructor(int no) throws ClassCastException, ArithmeticException { }
    public Guru99Constructor(int no, String name) throws RemoteException, SQLException { }
    public Guru99Constructor(int no, String name, String address) throws InterruptedException { }
}

ここでは、クラスに存在するコンストラクタのメタデータを取得するクラスを作成します。 Guru99Constructor.class:

コンストラクターのメタデータを取得する

package guru;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
public class Guru99ConstructorMetaDataTest {

    public static void main(String[] args) {
        // Create Class object for Guru99Constructor.class
        Class guru99Class = Guru99Constructor.class;

        // Get all the constructor information in the Constructor array
        Constructor[] guru99ConstructorList = guru99Class.getConstructors();

        for (Constructor constructor : guru99ConstructorList) {
            System.out.println("Constructor name : " + constructor.getName());

            int guru99Modifiers = constructor.getModifiers();
            System.out.println("Constructor modifier : " + Modifier.toString(guru99Modifiers));

            Class[] guru99ParamList = constructor.getParameterTypes();
            System.out.print("Constructor parameter types : ");
            for (Class class1 : guru99ParamList) {
                System.out.print(class1.getName() + " ");
            }
            System.out.println();

            Class[] guru99ExceptionList = constructor.getExceptionTypes();
            System.out.print("Exception thrown by constructors : ");
            for (Class class1 : guru99ExceptionList) {
                System.out.print(class1.getName() + " ");
            }
            System.out.println();
        }
    }
}
  1. クラスオブジェクトを作成しました Guru99コンストラクタクラス。
  2. すべてのコンストラクタのメタデータをConstructor配列に格納しました。
  3. クラスに存在するすべてのコンストラクタ名を出力しました。
  4. クラス内のコンストラクタのアクセス修飾子をすべて出力しました。
  5. コンストラクタのパラメータ型を出力しました。
  6. コンストラクタによってスローされた例外を出力しました。

コンストラクターのメタデータを取得する

コンストラクターのメタデータを取得する

よくあるご質問

リフレクションにより、フレームワークやAIツールは実行時にクラスを検査およびインスタンス化できます。依存性注入、シリアライゼーション、ORMマップなどを支える機能です。pingコンパイル時に正確なクラスを知らなくても、動的にプラグインをロードできます。

AIはリフレクションコードを迅速に生成できますが、そのコードは慎重にレビューする必要があります。リフレクションはアクセスチェックを回避し、セキュリティやパフォーマンスのリスクをもたらす可能性があるため、生成されたコードはテストと検証が必要です。

リフレクションは直接メソッド呼び出しよりも処理速度が遅く、プライベートメンバーにアクセスすることでカプセル化を損なう可能性があり、セキュリティや保守上の問題を引き起こす可能性があります。より簡単な方法がない場合にのみ使用すべきです。

はい。setAccessible(true)を使用すると、リフレクションによってプライベートフィールドの読み取りと変更、およびプライベートメソッドの呼び出しが可能になります。これはテストやフレームワークにとって強力な機能ですが、カプセル化を損ない、セキュリティ上の懸念を引き起こす可能性があります。