2011年1月30日日曜日

[Java]プライベートフィールドを更新する

UnitTestなどでprivateなフィールドをコードを修正せずに値を設定しようとした場合、publicなアクセッサメソッドを呼び出すか、リフレクションを利用するしかありません。
リフレクションを利用する場合、クラスの型情報を指定する必要がありますが、いちいち指定するのが面倒です。というとで、なかったら再起で呼び出すロジックを組んでみました。コードはこんな感じ。


/**
 * プライベート変数に値を設定します。
 *
 * @param obj インスタンス
 * @param fieldName 変数名
 * @param value 値
 */

public static void setPrivateField(Object obj, String fieldName,Object value) {

    setPrivateField(obj.getClass(), obj, fieldName, value);
}

/**
 * プライベートなstatic変数に値を設定します。
 * finalな変数はダメです。
 *
 * @param cls クラス
 * @param fieldName 変数名
 * @param value 値
 */

public static void setPrivateField(Class<?> cls, String fieldName,
        Object value) {

    setPrivateField(cls, null, fieldName, value);
}

/**
 * プライベートなstatic変数に値を設定します。
 * finalな変数はダメです。
 *
 * @param cls クラス
 * @param obj インスタンス
 * @param fieldName 変数名
 * @param value 値
 */

public static void setPrivateField(Class<?> cls, Object obj, String fieldName, Object value) {

    do {
        try {
            Field field = cls.getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(obj, value);
            break;
        } catch (NoSuchFieldException e) {
            // 親クラスからの取得にtry
            cls = cls.getSuperclass();
        } catch (Exception e) {
            // 例外
            e.printStackTrace();
            break;
        }
    } while (cls != null);

}

0 件のコメント: