2005-05-14(土) [長年日記]
_ リフレクションのメモ
オブジェクト内の状態をダンプでログに出そうと思って試行してみた。
toString()メソッドをオーバーライドして中身を出すようにすればよいのだが問題はその中身で、クラス毎に編集処理をいちいち書いては居られない。まあBigDecimalのようなValueObjectやHashのようなCollection系クラスなら内部表現は見せずにわかりやすく表示する必要があるかもしれないが、アプリ側でしかも異常終了時の解析用なので内部状態が全部出すほうが手っ取り早い。
そんなわけでリフレクションを使って全ての変数(Field)の内容を印字しようとしたのだけど、private変数は普通は見えないのですね(IllegalAccessExceptionになる)。
見えるようにする方法は探せば載ってるのだけど、キーワードをうまく設定しないとうまく絞り込めない。
結論としては、java.lang.reflect.FieldField#setAccessible(true) を呼ぶだけ。JDKのリフレクションに関するドキュメントではどうもたどりにくい。というかメソッドのJavaDocはあるけどこのメソッドへ誘導する説明がない。
try { .... /* private fieldへのアクセスを可にする */ field.setAccessible(true); Object value = field.get(objInstance); .... } catch (IllegalAccessException e) { ... } catch (SecurityException e) { /* セキュリティを高に設定しているとsetAccessible(true)時にthrowされる */ ... }
(キーワード:JavaのReflectionでprivate変数(field)の値を取得)
というようなことは今探したらこちらのページ(http://muimi.com/j/reflection/)にも簡単に例が書いてあったのだが、リンクだけでは検索率が上がらないため、とりあえず記す。
ちなみにFieldが配列だった場合はうまくtoString()が働かないので、Fieldの型に対して次のような処理が必要。
if(fieldClass.isArray()) { /* 配列要素の型を取り直す */ fieldClass = fieldClass.getComponentType(); }
なお、配列のサイズはjava.lang.reflect.ArrayのArray.getLength(obj)で取得できる。
FAQのような情報だったが、たどり着きにくいと労力が掛かるのよねえ。