【概要】
プライベートなメソッドやフィールドに外部から強引にアクセスする方法。カプセル化を破壊するので通常のプログラミングではまず使うべきではないが、ライブラリ利用時にどうしてもある状態をつくり出したい時や、private メソッドに対するテストケースを作成したいときに、テストケースのためだけにメソッドのシグニチャを変更したくないときなどには便利。かなり有名な方法ですが、一応、Java 関連の Tips ということで。

【キーワード】
private、プライベート、method、メソッド、field、フィールド、アクセス、変更、呼び出し、リフレクション、reflection、getDeclaredMethod、getDeclaredField

【詳細】

次の2つの Java ファイルを用意し、プログラムを実行する。

[プログラム: Person.java]

public class Person {
  private final String name;
  private final int age;

  public Person(String name, int age) {
    this.name = name;
    this.age = age;
  }
  
  public String getName() {
    return name;
  }
  
  public int getAge() {
    return age;
  }
  
  private void dumpInformation() {
    System.out.println("name=" + name + ", age=" + age);
  }
}

[プログラム: PersonHacker.java]

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class PersonHacker {
  public static void main(String[] args) throws Exception {
    Person person = new Person("小野和俊", 30);

    // 外部からのプライベートメソッドの呼び出し
    Method dumpInformationMethod =
      person.getClass().getDeclaredMethod("dumpInformation", new Class[] {});
    dumpInformationMethod.setAccessible(true);
    dumpInformationMethod.invoke(person, new Object[] {});

    // 外部からのプライベート& final なフィールドを変更
    Field nameField = person.getClass().getDeclaredField("name");
    nameField.setAccessible(true);
    nameField.set(person, "Kazutoshi Ono");
    System.out.println("name: " + person.getName());
  }
}