LoginSignup
18
16

More than 5 years have passed since last update.

Java リフレクションでprivteなフィールドを参照・更新したりメソッドを実行する方法

Last updated at Posted at 2016-07-25

JUnitテストで、privateなフィールドを参照・更新したり、メソッドを実行する必要がありましたので、リフレクションを使ったアクセス方法を整理します。

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class Test {
  static class X {
    private int num;           // privateな値
    private List<String> list; // privateなオブジェクト
    private String greeting(String name, int age) { // privateなメソッド
      return name + "(" + String.valueOf(age) + "): Hello!";
    }
    X(int i) {
      num = i;
      list = new ArrayList<String>();
      for (int j = 0; j < i; j++) {
        list.add(String.valueOf(j));
      }
    }
  }

  public static void main(String[] args) {
    X x = new X(10); // privateメンバへアクセスしたいオブジェクト

    try {
      Class<X> xClass = X.class; // Xクラスのクラスインスタンスを取得

      // privateな値の参照と変更
      Field xNumField = xClass.getDeclaredField("num");
      xNumField.setAccessible(true);
      System.out.println(xNumField.getInt(x)); // 10
      xNumField.setInt(x, 5); // 5をセット
      System.out.println(xNumField.getInt(x)); // 5

      // privateなオブジェクトの参照と変更
      Field xListField = xClass.getDeclaredField("list");
      xListField.setAccessible(true);
      List<String> xList = (List<String>)xListField.get(x);
      System.out.println(xList); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      xList.add("10");
      xListField.set(x, xList); // "10"を追加したリストをセット
      System.out.println(xListField.get(x)); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

      // privateなメソッドを実行
      Class[] argClasses = { String.class, int.class }; // 引数のクラス配列
      Method xGreetingMethod = xClass.getDeclaredMethod("greeting", argClasses);
      xGreetingMethod.setAccessible(true);
      Object[] argObjects = { "Tanaka", 28 }; // 引数のオブジェクト配列
      System.out.println(xGreetingMethod.invoke(x, argObjects)); // Tanaka(28): Hello!

    } catch (NoSuchFieldException e) {
      e.printStackTrace();
    } catch (SecurityException e) {
      e.printStackTrace();
    } catch (IllegalArgumentException e) {
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    } catch (NoSuchMethodException e) {
      e.printStackTrace();
    } catch (InvocationTargetException e) {
      e.printStackTrace();
    }
  }
}
18
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
16