« faad2-2.7でunrecognized command line option "-iquote" | トップページ | ココログに画像付きの投稿ができなくなった? »

2009/04/04

インナークラスを生成する

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" | トップページ | ココログに画像付きの投稿ができなくなった? »

プログラミング」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/18902/44558348

この記事へのトラックバック一覧です: インナークラスを生成する:

« faad2-2.7でunrecognized command line option "-iquote" | トップページ | ココログに画像付きの投稿ができなくなった? »