0Pricing
Java Academy · レッスン

メソッドの呼び出しとフィールドへのアクセス

Method.invoke と Field.set を setAccessible と組み合わせ、private メソッドを呼び出してアクセスできないフィールドを設定します。

「メソッドの呼び出しとフィールドへのアクセス」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。

setAccessible:可視性の回避

field.setAccessible(true)または method.setAccessible(true)を呼び出すと、Java のアクセス制御を回避できます。private メンバーにアクセスするために必要です。Java 9 以降では、適切なモジュールアクセスも必要です。

Field f = User.class.getDeclaredField("name");
f.setAccessible(true);
User u = new User("Alice", 30);
System.out.println(f.get(u));  // "Alice"
f.set(u, "Bob");               // mutate the private field
System.out.println(u.getName()); // "Bob"

フィールド値の読み取り

field.get(instance)を使用すると、任意のフィールド値を読み取れます(プリミティブ型はボックス化されます)。static フィールドの場合は、インスタンスとして nullを渡します。

Field f = MyClass.class.getDeclaredField("count");
f.setAccessible(true);
int count = (int) f.get(null); // static field → null instance

フィールド値の設定

field.set(instance, value)を使用してフィールドに値を書き込みます。値の型は一致しているか、自動アンボックス化できる必要があります。現代の JVM でリフレクションにより finalフィールドを設定した場合の動作は未定義です。

Field nameField = User.class.getDeclaredField("name");
nameField.setAccessible(true);
nameField.set(user, "Charlie");

リフレクションによるメソッド呼び出し

Methodオブジェクトを取得し、setAccessible(true)を呼び出してから、method.invoke(instance, args...)で呼び出します。戻り値の型は Objectです。

Method greet = User.class.getDeclaredMethod("greet", String.class);
greet.setAccessible(true);
String result = (String) greet.invoke(user, "World");
System.out.println(result);

InvocationTargetException の処理

呼び出したメソッドが例外をスローすると、リフレクションによって InvocationTargetExceptionにラップされます。getCause()で元の例外を取り出します。

try {
    method.invoke(obj, args);
} catch (InvocationTargetException e) {
    Throwable cause = e.getCause();
    System.err.println("Method threw: " + cause.getMessage());
} catch (IllegalAccessException | NoSuchMethodException e) {
    System.err.println("Reflection error: " + e.getMessage());
}

static メソッドの呼び出し

static メソッドを呼び出す場合は、インスタンス引数として nullを渡します。

Method parseInt = Integer.class.getDeclaredMethod("parseInt", String.class);
int value = (int) parseInt.invoke(null, "42"); // null = static
System.out.println(value); // 42

コンストラクターによるインスタンスの生成

Constructorを取得し、private コンストラクターの場合は setAccessible(true)を呼び出してから、newInstance(args...)を実行します。

Constructor<User> ctor = User.class.getDeclaredConstructor(String.class, int.class);
ctor.setAccessible(true);
User u = ctor.newInstance("Diana", 28);
System.out.println(u);

フレームワークでのリフレクション:Spring DI

Spring はリフレクションを使用して Bean をインスタンス化し、依存関係を注入します。private コンストラクターを呼び出し、private フィールドを設定してアプリケーションコンテキストを構成します。

Java 9 以降のモジュールアクセス

Java 9 以降では、モジュールによって setAccessibleがデフォルトで制限されます。クラスが名前付きモジュールにある場合は、パッケージを open にする必要があります。--add-opens java.base/java.lang=ALL-UNNAMEDを使用します。

// JVM flag to open a package for reflection:
// --add-opens java.base/java.lang=ALL-UNNAMED

高速な代替手段としての MethodHandles

MethodHandles.lookup().findVirtual()はリフレクションによるメソッド呼び出しを提供し、JIT 最適化後は直接呼び出しに近い性能を実現します。パフォーマンスが重要なライブラリコードで推奨されます。

MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(User.class, MethodHandles.lookup());
MethodHandle handle = lookup.findVirtual(User.class, "getName", MethodType.methodType(String.class));
String name = (String) handle.invoke(user);

リフレクションのベストプラクティス

Field/Methodオブジェクトをキャッシュし、ホットループ内で取得しないでください。リフレクションはサービスクラスでラップします。パフォーマンスが必要な場合は MethodHandles を検討します。可能な場合はリフレクションよりインターフェースを優先します。

理解度チェック

リフレクションで呼び出したメソッドが例外をスローした場合、その原因をラップする例外は何ですか?

まとめ

setAccessible(true)を使用して private メンバーにアクセスします。method.invoke()でメソッドを呼び出します。InvocationTargetExceptionから元の例外を取り出します。リフレクションで扱うオブジェクトをキャッシュし、ホットパスでは MethodHandles を優先します。

よくある質問

「メソッドの呼び出しとフィールドへのアクセス」レッスンは無料ですか?

はい。「メソッドの呼び出しとフィールドへのアクセス」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。

「メソッドの呼び出しとフィールドへのアクセス」で何を学びますか?

Method.invoke と Field.set を setAccessible と組み合わせ、private メソッドを呼び出してアクセスできないフィールドを設定します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Java Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「メソッドの呼び出しとフィールドへのアクセス」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このJava Academyレッスンでコードを書いて実行できますか?

はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. リフレクションによるクラスの調査
  2. メソッドの呼び出しとフィールドへのアクセス
  3. InvocationHandler による動的プロキシ
  4. リフレクションの性能と代替手段
← Java Academyに戻る