【Java】java.lang.reflect.Methodの使い方3選

■概要

java.lang.reflect.MethodJavaリフレクションAPI の一部で、実行時にクラスのメソッドにアクセスしたり呼び出したりするために使用。
「クラス名やメソッド名がコンパイル時に決まっていない」ケースで活躍する。

▼用途の例

フレームワーク開発(Spring, JUnit など)
→ アノテーション付きメソッドを探して実行する

汎用ツール
→ メソッド名を文字列で受け取り動的に実行する

シリアライザ/デシリアライザ
→ getter/setter を動的に呼び出す

▼注意事項

  • リフレクションは パフォーマンスが通常の呼び出しより遅い
  • カプセル化を破る(private呼び出しなど)ので使いすぎ注意
  • Javaのモジュールシステム(Java 9以降)ではアクセス制限に影響を受ける場合あり

■1. メソッドを取得する

・サンプルコード

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class SampleClass {

  public void sayHelloName(String name) {
    System.out.printf("Hello %s !!%n", name);
  }
}

public class GetMethod {

  public static void main(String[] args)
      throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
    // classを取得
    Class<?> sampleClass = SampleClass.class;

    // メソッドを取得
    Method method = sampleClass.getMethod("sayHelloName", String.class);

    // インスタンス作成
    Object obj = sampleClass.getDeclaredConstructor().newInstance();

    // メソッドを実行
    method.invoke(obj, "AAA");
  }

}

・実行結果

Hello AAA !!

■2. privateメソッドにアクセスする

・サンプルコード

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class PrivateMethodClass {

  private String saySecretMessage(String message) {
    return String.format("Secret Message: %s", message);
  }
}

public class AccessPrivateMethod {

  public static void main(String[] args)
      throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
    Class<?> sampleClass = PrivateMethodClass.class;
    Method method = sampleClass.getDeclaredMethod("saySecretMessage", String.class);

    // private method アクセス許可
    method.setAccessible(true);

    Object obj = sampleClass.getDeclaredConstructor().newInstance();
    String result = (String) method.invoke(obj, "accessed private method");

    System.out.println(result);
  }
}

・実行結果

Secret Message: accessed private method

■3. クラス内のすべてのメソッドを一覧取得

・サンプルコード

import java.lang.reflect.Method;

class MethodList {

  public void method1() {
    // nop
  }

  private int method2(int num) {
    return num * 2;
  }

  protected String method3() {
    return "hello";
  }
}

public class SelectMethodList {

  public static void main(String[] args) {
    Class<?> sampleClass = MethodList.class;

    // 宣言されたすべてのメソッド(private含む)
    for (Method m : sampleClass.getDeclaredMethods()) {
      System.out.println("Declared: " + m);
    }
  }
}

・実行結果

Declared: public void MethodList.method1()
Declared: private int MethodList.method2(int)
Declared: protected java.lang.String MethodList.method3()

コメント

タイトルとURLをコピーしました