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