Javaのクロージャをいじってみた。(1)

BGGAのクロージャサイト(http://javac.info/) の
プロトタイプ実装をいじってみた。

マイコミジャーナルに概要を書いた記事があるようです。

今回いじってみたのは2008-07-07版と2008-07-13版のプロトタイプ実装。
JSRもドキュメントもちゃんと読まずにいじっているけど
まあいいや。



1.単純実装の逆コンパイルして中身見る
・クロージャを用いたjavaコード

public class SimpleClosure {
  public static void main(String[] args) {
    int sum = { int x, int y => x + y }.invoke(3, 4); // return 7
    System.out.println(sum);
  }
}

・下のコードは上記コードをコンパイルし、jadで逆コンパイルしたコード

import java.io.PrintStream;
import javax.lang.function.III;
public class SimpleClosure {

  public SimpleClosure() {}

  public static void main(String args[]) {
    static class _cls1 implements III {
      public final int _2B_invoke(int j, int k) {
        return j + k;
      }
      
      public final int invoke(int j, int k) {
        return _2B_invoke(j, k);
      }
    }
    int i = _2B_INSTANCE0.invoke(3, 4);
    System.out.println(i);
  }
  // ↓クロージャの実体(staticのメンバとして記述される)
  public static final _cls1 _2B_INSTANCE0 = new _cls1();
}

逆コンパイルで気づいた点
 ・クロージャの場合実際はstaticメンバとして宣言されるため、
  深いforループの中でもnewが連発されることはありません。
  この点は無名クラスよりクロージャが有利な点ですね。

 ・なぞのインタフェースが生成されている。
  コンパイルするとIIIというインタフェースが生成されている。
  (自動生成されるインタフェース名は作る物により色々変わる)
  3段のパッケージ(フォルダ)の自動生成といい、クロージャでは豪快に
  生成する。

   【生成される物】
     classes/javax/lang/function/III.class
     classes/javax/lang/functio n/unrestricted/III.class

  でもジェネリクスのイレイジャ処理に比べ結果が想像しやすいから
  実現方法としては好きだ。

2.戻り値の書き方
  戻り値は最後のステ ートメントのリターンがクロージャの戻り値として
  認識される。
  じゃあ、最後のステートメントが戻り値持たない処理はどうなるのさと
  思いまして。いじってみたところ以下のようになりました。


// クロージャ内の記述
List<string> ret = new ArrayList<string>();
for(String str : args) {
  ret.add("戻り値" + str);
}

  上記の ret を戻り値にしたいとき。

return ret;



  と書くと、戻り値型が違うというコンパイルエラーになる。

ret

  とだけ書くと逆にOK。最後の行は";","return"はついちゃだめ。
  書くとコンパイルエラーで弾かれる。

3.クロージャ対応javadoc
 同梱されているjavadocコマンドを実行するとクロージャ型以下のような
 出力になる。



 
 

コメント

このブログの人気の投稿

日食ツアーその後

NashornがOpenJDKのリポジトリに入ってたのでビルドしてみた