レベルエンター山本大のブログ

面白いプログラミング教育を若い人たちに

BLOCKVROCKリファレンス目次はこちら

Java with CGLIB でC#ライクなDelegateを使う。

Javaの言語仕様には、C#で言うDelegateは無いが、
CGLIBでDelegateの仕組みが提供されている。
C#にインスパイアされて作ったって書いてた。

Delegateというのは、(御幣を承知で言えば)
メソッドへのポインタをオブジェクトインスタンスから切り離して
参照型変数に保持して利用するというもの。

継承なしでテンプレートメソッドが利用できるので、制御の反転がより柔軟にできる。
C#ではイベント処理に使われる。

やってみよう

■CGLIBのサイト
http://cglib.sourceforge.net/

とりあえず、CGLIBをダウンロードする。
ASMという別のライブラリに依存しているが、
cglib-nodep-X.X_X.jarを使えばこれ一つで動く。

僕はBetaは使わず以下のものを使った。
cglib-nodep-2.1_3.jar


まずは、Delegateを作る。Interfaceとして実装だ。
EventDelegate.java

public interface EventDelegate {
    void doEvent(Object target);
}

そして、以下がデリゲートに委譲するコード。
Main.java

import net.sf.cglib.reflect.MethodDelegate;

// 起動メソッドを持つクラス
public class Main {
    public static void main( String[] args ) {
        Pojo instance = new Pojo();

        // デリゲートにメソッド委譲
        EventDelegate event = (EventDelegate)MethodDelegate.create(instance, "alternateEventMethod", EventDelegate.class);

        // デリゲートを経由してメソッドを呼び出す。
        event.doEvent( "hello" );
    }
}

// ビジネスオブジェクト
class Pojo{
    // デリゲート経由で呼び出されるメソッド
    public void alternateEventMethod( Object arg ) {
        System.out.println( arg );
    }
}

EventDelegate型のオブジェクトにメソッドへのポインタが渡される。

Delegateが持つメソッドの引数・戻り値が一致するメソッドであれば
Delegateに保持することが可能となる。(メソッド名は一致しなくて良い)


そして以下のコマンドで、実行。
※作ったソースとライブラリをカレントディレクトリにおいて実行。

javac -cp cglib-nodep-2.1_3.jar  *.java
java -cp .;cglib-nodep-2.1_3.jar Main

「hello」と表示されるはずだ。

これを使えば、C#ライクなイベントドリブンフレームワークが作れそうだ。