Rhino詳細:JavaScriptからJavaインターフェースの実装とクラスの継承

白石俊平(あゆた)
2008-02-12 08:30:00
  • このエントリーをはてなブックマークに追加

方法その2:クロージャを使う

java.lang.Runnableのように、メソッドが一つしか定義されていないインターフェースにおいては、クロージャ(関数オブジェクト)を実装クラスの代わりに用いることができます。この仕組みを使うと、前述の例は以下のように書き換えることができます。

var thread = new java.lang.Thread(function() {
    java.lang.System.out.println("Hello");
});
thread.start();

 また、クロージャをインターフェース実装の代わりに使えるのは、メソッドが一つの場合に限りません。定義されているメソッドのシグネチャが全て同一なインターフェースに対しても用いることができます。

 例えば、GUIコンポーネント上でのマウスイベントを処理するためのインターフェース、java.awt.event.MouseListenerなどは、mouseEntered()やmouseExited()など、同じシグネチャのメソッドのみから構成されています。

 以下の例は、ウィンドウ上でマウスイベントが発生したら、標準出力に「マウスイベントが発生しました!」と表示します。

// ウィンドウの生成
var win = new Packages.javax.swing.JFrame();
win.setSize(200, 200);

// java.awt.MouseListenerの実装としてクロージャを指定
win.addMouseListener(function(event) {
    java.lang.System.out.println("マウスイベントが発生しました!");
});
win.setVisible(true);

 しかしこの方法では、実際どのメソッドが呼び出されたのかを知ることができないため、様々なイベントに対して別々の処理を行うことができません。「実際に呼び出されたメソッドの名称」を知るために、インターフェースに定義されたメソッドが持つ本来の引数に加えて、メソッド名を受け取るようにクロージャを定義することができます。

// メソッド名を受け取るようクロージャを修正
win.addMouseListener(function(event, methodName) {
    if (methodName == "mouseClicked") {
        java.lang.System.out.println("クリックされました!");
    } else {
        java.lang.System.out.println("マウスイベントが発生しました!");
    }
});

 こうして、インターフェースの実装にクロージャを用いることにより、「スクリプト言語らしい」コンパクトなコードを実現することができます。

  • コメント(2件)
#1 さくらば   2008-02-19 23:37:43
最後のサンプルは Java SE 6 の Rhino では動作しません。Java SE 6 の JavaAdapter は Sun の実装に変更されており、単一インタフェースのみインプリメントすることができます。
#2 大野晋一   2008-02-21 15:08:21
さくらばさん、ご指摘ありがとうございます。おっしゃるとおり、Java SE 6とともに配布されるものでは無理で、最新のRhinoを使う必要がありますね。
  • 新着記事
  • 特集
  • ブログ
このサイトでは、利用状況の把握や広告配信などのために、Cookieなどを使用してアクセスデータを取得・利用しています。 これ以降ページを遷移した場合、Cookieなどの設定や使用に同意したことになります。
Cookieなどの設定や使用の詳細、オプトアウトについては詳細をご覧ください。
[ 閉じる ]