Java Reflection API 完全マスター:実践ガイドとコード例
Java のリフレクションとは?
Java リフレクションは、クラスのあらゆる機能を実行時に分析・変更するプロセスです。Java のリフレクション API は、フィールド、メソッド、コンストラクタなど、クラスとそのメンバーを実行時に操作するために使用されます。
リフレクション API の利点の1つは、クラスの private メンバーも操作できることです。
java.lang.reflect パッケージはリフレクションを実装する多くのクラスを提供します。java.lang.Class クラスのメソッドを使って、特定クラスの完全なメタデータを収集します。
このチュートリアルで学ぶ内容:
- リフレクションとは
- java.lang.reflect パッケージのクラス
- java.lang.Class で使用されるメソッド
- クラスの完全情報を取得する方法
- 例 1: クラスのメタデータ取得
- 例 2: 変数のメタデータ取得
- 例 3: メソッドのメタデータ取得
- 例 4: コンストラクタのメタデータ取得
java.lang.reflect パッケージのクラス
リフレクション実装のための java.lang.reflect パッケージの主なクラス:
- Field:変数のデータ型、アクセス修飾子、名前、値などの宣言情報を取得
- Method:メソッドのアクセス修飾子、戻り値型、名前、パラメータ型、例外型などの宣言情報を取得
- Constructor:コンストラクタのアクセス修飾子、名前、パラメータ型などの宣言情報を取得
- Modifier:特定のアクセス修飾子に関する情報を取得
java.lang.Class で使用されるメソッド
- Public String getName():クラス名を返す
- public Class getSuperclass():スーパークラスの参照を返す
- Public Class[] getInterfaces():指定クラスが実装するインターフェースの配列を返す
- Public int getModifiers():指定クラスの修飾子を表す整数値を返す。これを public static String toString(int i) メソッドに渡すと、そのクラスのアクセス指定子を返す
クラスの完全情報を取得する方法
変数、メソッド、コンストラクタの情報を得るには、クラスのオブジェクトを作成する必要があります。
public class Guru99ClassObjectCreation {
public static void main (String[] args) throws ClassNotFoundException {
// 1 - Class.forName() メソッド使用
Class c1 = Class.forName("Guru99ClassObjectCreation");
// 2 - getClass() メソッド使用
Guru99ClassObjectCreation guru99Obj = new Guru99ClassObjectCreation();
Class c2 = guru99Obj.getClass();
// 3 - .class 使用
Class c3 = Guru99ClassObjectCreation.class;
}
}
例 1:クラスのメタデータ取得
以下の例では、クラス名、スーパークラス名、実装インターフェース、アクセス修飾子などのメタデータを取得する方法を示します。
以下の Guru99Base.class のメタデータを取得します:

import java.io.Serializable;
public abstract class Guru99Base implements Serializable, Cloneable {
}
- クラス名:Guru99Base
- アクセス修飾子:public と abstract
- 実装インターフェース:Serializable と Cloneable
- 明示的にクラスを拡張していないため、スーパークラスは:java.lang.Object
以下のクラスで Guru99Base.class のメタデータを取得して出力:

import java.lang.reflect.Modifier;
public class Guru99GetclassMetaData {
public static void main (String[] args) throws ClassNotFoundException {
// Guru99Base.class の Class オブジェクト作成
Class<Guru99Base> guru99ClassObj = Guru99Base.class;
// クラス名出力
System.out.println("Name of the class is : " + guru99ClassObj.getName());
// スーパークラス名出力
System.out.println("Name of the super class is : " + guru99ClassObj.getSuperclass().getName());
// getInterfaces() で実装インターフェースリストを Class 配列として取得
Class[] guru99InterfaceList = guru99ClassObj.getInterfaces();
// foreach で実装インターフェース出力
System.out.print("Implemented interfaces are : ");
for (Class guru99Class1 : guru99InterfaceList) {
System.out.print(guru99Class1.getName() + " ");
}
System.out.println();
// getModifiers() と Modifier.toString() でアクセス修飾子取得
int guru99AccessModifier = guru99ClassObj.getModifiers();
System.out.println("Access modifiers of the class are : " + Modifier.toString(guru99AccessModifier));
}
}
- getName メソッドでクラス名出力
- getSuperClass().getName() でスーパークラス名出力
- 実装インターフェース名出力
- クラスで使用されるアクセス修飾子出力


例 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";
}
上記クラスの変数メタデータ取得手順:
- 上記クラスのクラスオブジェクト作成:
Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData(); Class guru99ClassObjVar = guru99ClassVar.getClass();
- getFields() または getDeclaredFields() でメタデータを Field 配列として取得:
Field[] guru99Field1 = guru99ClassObjVar.getFields(); Field[] guru99Field2 = guru99ClassObjVar.getDeclaredFields();
getFields() メソッドは、指定クラスおよびそのスーパークラスの public 変数のメタデータを返します。
getDeclaredFields() メソッドは、指定クラスのみのすべての変数のメタデータを返します。
- 「public String getName()」メソッドで変数名取得
- 「public Class getType()」メソッドで変数のデータ型取得
- 「public xxx get(Field)」メソッドで変数の値取得。ここで xxx は取得したい値の型(byte、short 等)
- getModifier() と Modifier.toString(int i) でアクセス修飾子取得
Guru99VariableMetaData.class に存在する変数のメタデータを取得するクラス:

package guru;
import java.lang.reflect.Field;
public class Guru99VariableMetaDataTest {
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
// Guru99VariableMetaData.class のクラスオブジェクト作成
Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();
Class guru99ClassObjVar = guru99ClassVar.getClass();
// Guru99VariableMetaData クラスのすべてのフィールドメタデータ取得
Field[] guru99Field1 = guru99ClassObjVar.getDeclaredFields();
// 指定クラスの変数名、データ型、アクセス修飾子、値を出力
for (Field field : guru99Field1) {
System.out.println("Variable name : " + field.getName());
System.out.println("Datatypes 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();
System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *");
}
}
}
- Guru99VariableMetaData.class のクラスオブジェクト作成
- クラスのすべての変数メタデータを Field 配列で取得
- Guru99VariableMetaData.class のすべての変数名出力
- すべての変数のデータ型出力
- すべての変数のアクセス修飾子出力
- すべての変数の値出力


例 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");
}
}
上記クラスのメソッドメタデータ取得手順:
- クラスオブジェクト作成:
Guru99MethodMetaData guru99ClassVar = new Guru99MethodMetaData(); Class guru99ClassObjVar = guru99ClassVar.getClass();
- getMethods() と getDeclaredMethods() でメソッド情報を Method 配列として取得:
Method[] guru99Method1 = guru99ClassObjVar.getMethods(); Method[] guru99Method2 = guru99ClassObjVar.getDeclaredMethods();
getMethods() は指定クラスおよびスーパークラスの public メソッドメタデータを返します。
getDeclaredMethods() は指定クラスのみのすべてのメソッドメタデータを返します。
- getName() でメソッド名取得
- getReturnType() で戻り値型取得
- getModifiers() と Modifier.toString(int i) でアクセス修飾子取得
- getParameterTypes() でパラメータ型取得(Class 配列返却)
- getExceptionTypes() でスローされる例外取得(Class 配列返却)
Guru99MethodMetaData.class に存在するメソッドのメタデータを取得するクラス:

package guru;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Guru99MethodMetaDataTest {
public static void main(String[] args) {
// Guru99MethodMetaData.class のクラスオブジェクト作成
Class guru99ClassObj = Guru99MethodMetaData.class;
// 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();
System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *");
}
}
}
- Guru99MethodMetaData.class のクラスオブジェクト作成
- すべてのメソッドメタデータを Method 配列で取得
- クラスに存在するすべてのメソッド名出力
- メソッドの戻り値型出力
- すべてのメソッドのアクセス修飾子出力
- Guru99MethodMetaData.class のメソッドパラメータ型出力
- Guru99MethodMetaData.class のメソッドがスローする例外出力


例 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;
public class Guru99ConstructorMetaDataTest {
public static void main(String[] args) {
// Guru99Constructor.class のクラスオブジェクト作成
Class guru99Class = Guru99Constructor.class;
// すべてのコンストラクタ情報を Constructor 配列で取得
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.println("Exception thrown by constructors : ");
for (Class class1 : guru99ExceptionList) {
System.out.println(class1.getName() + " ");
}
System.out.println();
System.out.println("*******************************************");
}
}
}
- Guru99Constructor.class のクラスオブジェクト作成
- すべてのコンストラクタメタデータを Constructor 配列で取得
- クラスに存在するすべてのコンストラクタ名出力
- すべてのコンストラクタのアクセス修飾子出力
- Guru99Constructor.class のコンストラクタパラメータ型出力
- Guru99Constructor.class のコンストラクタがスローする例外出力


まとめ:
- Java のリフレクションプログラミングは、クラスとクラスメンバー(変数、メソッド、コンストラクタ)の情報取得と変更に役立つ
- リフレクション API は java.lang.reflect パッケージのクラスと java.lang.Class クラスのメソッドで実装
- java.lang.Class のよく使われるメソッド:getName()、getSuperclass()、getInterfaces()、getModifiers() 等
- java.lang.reflect のよく使われるクラス:Field、Method、Constructor、Modifier 等
- リフレクション API はクラスの private メソッドと変数にアクセス可能で、セキュリティ上の脅威になり得る
- リフレクション API は Java が提供する強力な機能だが、パフォーマンス低下、セキュリティ脆弱性、権限問題などのオーバーヘッドを伴う。したがって、操作を実行する最後の手段として扱うべき
Java
- C++クラスとオブジェクト:コード例付き実践ガイド
- C#クラスとオブジェクト実践チュートリアル:実例で学ぶオブジェクト指向の基礎
- C#抽象クラス実践チュートリアル:コード例で理解する設計パターン
- Java無名インナークラス完全ガイド:定義、構文、実践例
- Javaリフレクション完全ガイド:実行時のクラス・メソッド・フィールド検査
- Java ObjectInputStream完全ガイド:逆シリアル化の実践
- Java ObjectOutputStream完全ガイド:シリアル化、メソッド、実践例
- Java String.charAt()完全解説:構文、戻り値、例外、実例
- Java String.endsWith()マスター:文字列サフィックスチェック実例付き
- Java BufferedReader でファイル読み込み:実践ガイドと例
- Javaで挿入ソート:わかりやすい例とステップバイステップガイド