Java 8 の現状をチェック - 2013年5月下旬 (b91)
前回(2013-02-19)から3か月ほど経過しましたが、また少し状況が変わったようです。
今回は、EarlyAccess版ビルドをインストールしてみました。
リリースの延期
OpenJDKのサイトによれば、GA(=General Available,正式リリース?)は、来年の3月(2014-03-18)になるようです。
インストール
今回インストールしたバージョンは、b91です。
java version "1.8.0-ea" Java(TM) SE Runtime Environment (build 1.8.0-ea-b91) Java HotSpot(TM) Client VM (build 25.0-b33, mixed mode)
ラムダのバイトコード
ラムダ自体のサンプルは特になしです。
例によって、バイトコードがどうなっているかを調べました。
import java.util.function.IntFunction; final class Main { public static void main(String[] args) { IntFunction f = (a) -> a * 3; System.out.println(f.apply(4)); } private static Object fn(int a) { return a * 3; } }
javap -p -v の後半部分
private static java.lang.Object fn(int); descriptor: (I)Ljava/lang/Object; flags: ACC_PRIVATE, ACC_STATIC Code: stack=2, locals=1, args_size=1 0: iload_0 1: iconst_3 2: imul 3: invokestatic #6 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 6: areturn LineNumberTable: line 12: 0 private static java.lang.Object lambda$0(int); descriptor: (I)Ljava/lang/Object; flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC Code: stack=2, locals=1, args_size=1 0: iload_0 1: iconst_3 2: imul 3: invokestatic #6 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 6: areturn LineNumberTable: line 1: 0
privateのlambda$0メソッドが作られていて、メソッドfnとほとんど同じコードになっているのが分かります。見えないローカルメソッドに置き換えられています。
ただ一点、lambda$0の方にはflagsにACC_SYNTHETICが余計についています。これは、JVM仕様には
A method may be marked with the ACC_SYNTHETIC flag to indicate that it was generated by a compiler and does not appear in source code, unless it is one of the methods named in §4.7.8.
と書いてあります。ラムダのように、コンパイラが生成してソースコード上は見えないメソッドに付けられるフラグのようです。
ところで、ラムダの呼び出しの仕掛けはこれだけではなく、省略した最初の方にBootstrapMethodsという記述があり、invokedynamicの際に使われるようです。
また、これより古い実装では、内部クラスによる実装だったとか(未確認)。
この辺の詳細は、また機会があれば。
API関連とCompact Profiles
APIドキュメントを見てみます。
ラムダのためのパッケージ、java.util.functionとjava.util.streamが追加されています。
新しい日時APIのjava.timeも追加されています。
java.sqlのDate,Time,Timestampには、java.timeのクラスとの相互変換ユーティリティメソッドが追加されています。(Timestamp#toLocalDateTimeなど)
他にもパッケージのリストや各クラスのパッケージ表記の上部に、"compact1, compact2, compact3"のような見慣れない記述があります。
これは、"Compact Profiles"という機能のためのもので、JREフルセットでなくても動くアプリケーションを作るのに使うようです。
その他
ダイジェストでお送りします。
- interfaceのデフォルト実装メソッドは、JDBC-APIのようにinterfaceが多いAPIには向いていますね。JDBC4.2以降で追加されるメソッドはほとんどdefaultメソッドになるのかも。
- ラムダのために、primitiveラッパークラスにメソッドが追加されていたりします。でも、staticなhashCodeが追加されているのは単なるユーティリティ?
- Eclipseは、まだJava8使えません。誰かがIntelliJ IDEAを推奨されていました。今はフリーのがあるので、ちょっとだけcommunity editionを使ってみました。Java8使えましたよ!
またリリースが近くなったらまとめたいと思います。