アクセッサメソッドを使わずにprivateフィールドを取得したり書き換える

こんなことできると思いますか?
結論!!

できます!!
できるんです。
こんなこと可能にするのはリフレクションを使用します。
リフレクションとは・・・
指定したクラスのフィールドやメソッドやコンストラクタの情報を
探したり、使用したり、書き換えたりします。
基本的な使い方を見てみます。

public class Ref {

	public String sayHello() {
		return "Hello World";
	}
}

なんの変哲も無いクラスを作成します。
こいつを呼び出すと"Hello World"をかえします。
実際に呼び出してみます

import java.lang.reflect.Method;

public class Reflection1 {

	public static void main(String[] args) {
		try {
			Class c = Class.forName("Ref");
			Method method = c.getMethod("sayHello", null);
			Object result =  method.invoke(c.newInstance(), null);
			System.out.println(result);
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("例外発生");
		}
	}
}

これを実行するとHello Worldがコンソールに出力されます。
もし、指定したメソッドが無かっり
クラスが存在しなかったりした場合は例外が投げられます。

もし呼び出すクラスがパッケージ内にある場合は
絶対パスを指定する必要があります。

getMethodの第二引数はパラメータ
invokeの第二引数は呼び出すメソッドの引数を指定します。
詳しくはJavaAPIを参照してください。

で、ひねくれもののdamePGは思いました。
「なんとかprivateのフィールド情報を取得して書き換えできないかなぁ・・・・」

試験としてこのようなクラスを用意しました。

public class Property {

	private int id = 1;
	
	private  String name = "damePG";
	
	private  String pass = "damedame";
}

うを!!!
完全に守られてます。
ドラクエで言うとメタルスライム級の防御力です。

でもね、ドラクエでもFFでも漫画でも
現実社会でも完全防御を打ち崩す必殺技が
必ず存在します。
Javaもきっとあるはず。
で結論打ち崩しました。
コードはこちら

import java.lang.reflect.Field;

public class Reflection2 {

	private static Field f;
	
	static {
		try {
			f = Property.class.getDeclaredField("id");
		} catch (SecurityException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} 
	}
	
	public static void main(String[] args) throws SecurityException,NoSuchFieldException, IllegalArgumentException, IllegalAccessException{
		Property p = new Property();
		
		f.setAccessible(true);
		f.set(p, 2);
		System.out.println(f.get(p));
	}
}

上から追っていきます。
まずstaticなFieldクラスの変数を用意します。
次にstatic初期化子でどこのクラスのなんていうフィールドかを書きます。(try-catchの中)

mainメソッドでFieldクラスのメソッドを駆使します。
(詳細はJavaAPIで調べてください)
これを実行すれば、idには2が入ります。

あまり現場では使用しないと思いますが、
たまにはこういうのもいいです。

ひょんなことからリフレクションの話題になったので
一回やってみました。

改めて、APIの大切さをまじまじ感じた
damePGでした。

あるとおもいます!!