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のセキュリティレベルと関連してるらしく、いつも動くコードではないそうです。詳細はそのうち調べます≧(´▽`)≦。