メンバ変数に保持していれば、リフレクションで取り出すことができるので、実行も比較的楽なんですが、コレがメソッド内のみで利用されている場合、この内部クラスを外部からインスタンス化する必要があります。
ちょっと面倒ですが、外部からインスタンス化する方法を紹介します。
■インスタンス化するコード
try {
TargetClass target = new TargetClass();
//配列の0番目は決めうち
Class<?> clss = TargetClass.class.getDeclaredClasses()[0];
//コンストラクタを取り出す。引数はそのアウタークラスになる
Constructor<?> cons = clss.getDeclaredConstructor(new Class[]{TargetClass.class});
//コンストラクタを使ってインスタンスを生成する
cons.setAccessible(true);
Object inner = cons.newInstance(new Object[]{target});
//メソッド実行
System.out.println(inner.toString());
} catch (SecurityException e) {
} catch (NoSuchMethodException e) {
} catch (IllegalArgumentException e) {
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
TargetClass target = new TargetClass();
//配列の0番目は決めうち
Class<?> clss = TargetClass.class.getDeclaredClasses()[0];
//コンストラクタを取り出す。引数はそのアウタークラスになる
Constructor<?> cons = clss.getDeclaredConstructor(new Class[]{TargetClass.class});
//コンストラクタを使ってインスタンスを生成する
cons.setAccessible(true);
Object inner = cons.newInstance(new Object[]{target});
//メソッド実行
System.out.println(inner.toString());
} catch (SecurityException e) {
} catch (NoSuchMethodException e) {
} catch (IllegalArgumentException e) {
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
第一引数が該当のクラスのアウタークラスになるのがルール。
■ターゲットのクラス(例)
public class TargetClass {
public void doExec(){
new TargetInnerClass().subExec();
}
//このクラスの単体テストが難しい...
private class TargetInnerClass{
public void subExec(){
}
}
}
1 件のコメント:
こんにちは。
テストを考慮した設計、重要ですね!
コメントを投稿