argius note

プログラミング関連

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が追加されています。
新しい日時APIjava.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使えましたよ!


またリリースが近くなったらまとめたいと思います。