北海道苫小牧市出身の初老PGが書くブログ

永遠のプログラマを夢見る、苫小牧市出身のおじさんのちらしの裏

privateは絶対領域か?

privateのフィールドは操作出来ないことになっているが、100%絶対と言うわけでもないみたいです。

import java.lang.reflect.Field;

/* イミュータブルなクラス */
class PersonalData{
    private String name = "Hiratara";

    public String toString(){
	return name;
    }

}

/* イミュータブルなクラスからデータを盗む・改竄 */
class DataTheef{
    static public void main(String[] strs){
	/* 変更不可のインスタンス */
	PersonalData pd = new PersonalData();
	/* 名前はHiratara */
	System.out.println(pd);

	//下記はコンパイルエラー
	//System.out.println(pd.name);

	/* ここから、リフレクション */
	Class c   = pd.getClass();
	Field[] fields = c.getDeclaredFields();
	for(Field f: fields){
	    f.setAccessible(true);
	    try{
		/* 盗んだり改竄したり */
		System.out.println("steal private name: " + f.get(pd));
		System.out.println("change your name to 'Horiemon'!!");
		f.set(pd, "Horiemon");
	    }catch(IllegalAccessException e){
		System.out.println("Error occured...");
		e.printStackTrace();
		System.exit(-1);
	    }
	}

	/* 名前がHoriemonに改竄されている */
	System.out.println(pd);

    }
}

getDeclaredFields()でpublicじゃないフィールドも取得ができ、setAccessible()でtrueをセットするとjavaのアクセス権限チェック機構が効かなくします。

ただし、これはjava VMのセキュリティレベルと関連してるらしく、いつも動くコードではないそうです。詳細はそのうち調べます≧(´▽`)≦。