privateで宣言されたフィールドは、getterやsetterがないとアクセスすることはできませんが、Javaの標準APIであるリフレクションを使用するとアクセスが可能となります。
ただ、これを使用してしまうと何のためにアクセス制御(カプセル化)をしているのか意味がなくなってしまうので、テストをする際にどうしてもモック化が必要であった場合等に重宝します。
まずは、以下のようにprivateなフィールドをコンストラクタのみのクラスがあったとします。
// TestField.java public class TestField { private String value; public TestField(String value) { this.value = value; } }
通常では、どうやってもvalue値を取得したりセットしたりすることはできませんが、
以下のようにリフレクションを使用するとそれが可能となります。
// Test.java import java.lang.reflect.Field; public class Test { public static void main(String[] args) { TestField test = new TestField("foo"); try { Field field = test.getClass().getDeclaredField("value"); //フィールドにアクセスできるようにする field.setAccessible(true); // フィールドの値を取得 String value = String.valueOf(field.get(test)); System.out.println(value); // フィールドの値を変更 field.set(test, "bar"); value = String.valueOf(field.get(test)); System.out.println(value); } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); } } }
一つ注意点としては、上記のfield.setAccessible(true);
を記述しないとフィールドへのアクセスはできず
IllegalAccessExceptionがスローされてしまうので、忘れずに記述しましょう。