気になるJavaのクロージャ

次期JavaプラットフォームとなるJava SE 7で導入される新機能はいくつかあるが、その中でも最もその動向が注目されているものがクロージャだろう。クロージャについてはまだ提案者の間でも議論がまとまっておらずJCPには提案されていないが、その準備サイトである「Closures for the Java Programming Language」において現行案が公開されている。

現在、上記サイトにはJSRのドラフトや現在の暫定仕様も公開されているが、これは通称「BGGA版」と呼ばれるもので、Gilad Bracha、Neal Gafter、James Gosling、Peter von der Aheの4名が中心となって提案しているもの。ただしBGGA版の仕様もさまざまな意見を取り入れながら逐次修正されているため、はっきりと形が定まるのはもう少し先になるかもしれない。

本稿ではひとまず現段階で公開されている情報をもとに、Javaにおけるクロージャがどういうものになりそうなのかを紹介したい。

Javaのクロージャの目的

まずJSRのドラフトを見てみると、このJSRはJavaにおいて一般的に"クロージャ"と呼ばれるメカニズムを利用できるようにするものとなっている。そしてこの仕様のメリットとして以下のようなものが挙げられている。

  1. 無名クラスを使って実装されている一部のプログラムを簡素化できる
  2. リソースの完了などにおける種々の問題を解決できる強力なライブラリが提供できる
  3. 並行処理フレームワーク(java.util.concurrent)の実装をシンプルにできる
  4. Aggregate Operationのための新たな種類の並行処理フレームワークを提供できる
  5. Java言語のデザインをAPIのデザインによって拡張することができるようになる

従来、無名クラスを利用することでクロージャに近いコードを記述することができた。一部のプログラムではこれを利用してコールバックなどの機能を実現していたが、フル機能のクロージャが正式にサポートされれば、それらのコードにおけるさまざまな問題を解決することができるという。

またこのJSRではクロージャと同時にそれを利用した新しいステートメントを提案している。例えば同期処理のためのwithLockステートメントや、繰り返し処理のためのforeachステートメントである。クロージャを用いることでこれらの機能がよりシンプルに実現できるようになるとのこと。

4つ目の要素にある"Aggregate Operation"とは、ListやMapなどのコレクションに対する操作を指しているようだ。コレクションを操作するためのメソッドが、クロージャを使うことで非常にシンプルに呼び出しできるようになるとのこと。例としてはsortやfilterなどが挙げられている。

プロトタイプの実装を試す

さて、前述のサイトでは現時点におけるBGGAの仕様を実装したJavaコンパイラのプロトタイプも公開されている。これはOpenJDKプロジェクトによるJDK7の実装にクロージャの機能を追加したものであり、基本的なクロージャの構文を試してみることができる。なお、この実装を利用するためには別途JDK 5.0以降がインストールされ、javaコマンドやjavacコマンドがPATH環境変数に正しく含まれているる必要がある。

まず「closures.tar.gz」をダウンロードし、任意の場所に展開する。このファイルにはbinとlibの2つのディレクトリが含まれており、libにはクロージャの機能を実装したclosure.jarが、binにはそれを利用するためのシェルスクリプトおよびMS-DOS用のバッチファイルが用意されている。closure.jarにはクロージャを用いたJavaコードをコンパイルするためのコンパイラが含まれている。

binディレクトリにある各スクリプトはjavacやjavaコマンドをclosure.jarを利用するように変更するものだ。利用するにはコンソールを開いてbinディレクトリに移動し、通常と同様にコンパイル/実行すればよい。たとえばクロージャを使ったリスト1のプログラムをコンパイルするには、プロンプト1のようにする(Windowsのコマンドプロンプトの場合。%PATHFORCLOSURE%はclosures.tar.gzを展開した場所へのパス)。

FirstClosure.java - クロージャを使ったプログラム

public class FirstClosure {
    public static void main(String[] args) {
        int answer = { => 1234 }.invoke();
        System.out.println(answer);
    }
}

プロンプト1

> cd %PATH_FOR_CLOSURE%\bin
> javac FirstClosure.java

実際にはプロンプト2のようなコマンドが実行され、コンパイルが行われる。

プロンプト2

> javac -J-Xbootclasspath/p:"%PATH_FOR_CLOSURE%\lib\closure.jar" -source 7 -d FirstClosure.java

リスト1でクロージャを含んだコードが出てきたが、次回はこれらの構文についてもう少し詳しく紹介したいと思う。