インナークラスを生成する
Google Crome, 私の環境ではクラッシュする頻度がかなり高く、また、クラッシュ後に開いていたページを復元できないことも少なからずある。
それでも、起動時間や動作の速度といった性能が、他のブラウザよりCromeを使わせる要因になっていた。
しかし今回、クラッシュだけではなくブルースクリーンまで引き起こしてしまった。Cromeが原因かどうかははっきりしないが、このままの状況だとFirefoxに出戻ることにもなり兼ねない。
閑話休題。
Javaでは、コールバックの仕組みとして、コールする側にオブジェクトを渡しておき、イベントが発生するとそのオブジェクトで通知してもらう、というのが一般的である。
例えば、SwingではActionListenerインタフェースを実装したオブジェクトを用いて以下のようなコードを書く。
JButton button = new JButton("OK"); button.addActionListener(new Listener());
このListenerクラスがActionListenerインタフェースを実装しており、ボタンが押されるとactionPerformedメソッドでコールバックしてもらうことになる。
このようなコールバック発生をユニットテストしたいと考えたのだが、検索した限り、どうやってインナークラスを生成すればよいかが見つからなかったので、メモしておく。
インナークラス(内部クラス)と呼ばれるものにはいくつか種類があるが(参考:Java FAQ)、ここで扱うのは上記のListenerような「非staticなメンバ型」である。
サンプルコード
Swingのアプリケーションをサンプルとして用いる。コードはこちら。ボタンを押すとHello, worldと表示するプログラムで、今回、このボタンを押したことを通知するコールバック用クラスである"Listener"を外部から生成する。
インナークラスオブジェクトの取得
オブジェクトを生成するためにはコンストラクタが必要になる。そこで、Class#getDeclaredConstructorsメソッドを用いてコンストラクタを取得する。インナークラスオブジェクトは、"外部クラス$インナークラス"の書式でClass#forNameメソッド引数に渡せばよい。
// インナークラスを取得 Class clazz = Class.forName("MyWindow$Listener"); // コンストラクタを取得 Constructor[] constructors = clazz.getDeclaredConstructors();
インナークラスインスタンス生成
非staticなメンバ型のオブジェクトは、外部クラスインスタンスの中で生成する必要がある。コンストラクタの引数には、その外部クラスインスタンスを指定するようになっている。
Object obj = constructors[0].newInstance(outerObj);
getDeclaredConstructorsメソッドではコンストラクタが2個取得できるが、そのうち1個目を使用してオブジェクトを生成する。(2個目はどのような用途で用いるのか未調査)
あとは、生成したobjのメソッドを呼ぶことで、コールバック通知が行える。
前出のサンプルコード中にあったActionListenerインナークラス生成のサンプルはこちら。
« faad2-2.7でunrecognized command line option "-iquote" | トップページ | ココログに画像付きの投稿ができなくなった? »
この記事へのコメントは終了しました。
« faad2-2.7でunrecognized command line option "-iquote" | トップページ | ココログに画像付きの投稿ができなくなった? »
コメント