Java7からはクロージャが利用できる予定みたいですが、コンパイラの実装も出てきました。
http://javac.info/jsr166z.ztar まとまった資料は此方です。
http://gafter.blogspot.com/2007/01/definition-of-closures.html
どんな感じで書けるかというと、
{int, int => int} plus = {int x, int y => x + y};
int result = plus.invoke(1, 2);
というような感じでかけます。なんとなくイメージはつかめますよね。これは、
interface I{
int invoke(int n, int m);
}
I plus = new I(){
public int invoke(int n, int m){
return n + m;
}
};
int result = plus.invoke(1, 2);
というような感じに置き換えられます。内部でインターフェイスが作られます。仮引数として受け取るパターンはこちらです。ちなみに型パラメータもOKです。
public static <T> List<T> select(List<T> list, {T => boolean} filter){
List<T> result = new ArrayList<T>();
for(T t : list){
if(filter.invoke(t)){
result.add(t);
}
}
return result;
}
public void test(){
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
list = select(list, {Integer n => n % 2 == 0});
//list = [2,4]
}
既存のメソッドが1つだけのインターフェイスもクロージャとして使えます。例えば以下のような構文でスレッドを作成できます。
new Thread({=>
system.out.println(123);
}).start();
これは、
new Thread(new Runnable(){
public void run(){
System.out.println(123);
}
}).start();
に置換え可能です。
これからローカル変数や例外の扱いについても調べてみようと思いますが、雰囲気的には、
- 匿名クラスのシンタックスシュガー
- メソッドが1つのインターフェイスの定義のシンタックスシュガー
という感じがします。また色々書いていこうと思います。