Islands in the byte stream

Technical notes by a software engineer

AndroidにおけるJava8のサポート状況 2017年版

公式ドキュメントにありました。一言でまとめると、Android Oのpreviewが出た現在においても「Android N (API version 24)と同水準」となっています。

Use Java 8 language features | Android Studio

Android Studio 2.4 preview 4 (およびそれが要求するツールチェイン)の段階では、 desugar と呼ばれるツール(実体はAndroid Gradle PluginのTransform APIによるbytecode weaving tool)によって、一度javacでコンパイルしたバイトコードのJava8の言語機能(lambda, repating annotationsなど)をJava6水準のバイトコードに変換し、それをdxコマンドでdexにコンパイルするというプロセスを経るようです。このdesugarされたバイトコードは $subproject/build/intermediates/transforms/desugar/* にクラスファイルとして残されるので、どのようにバイトコードが変更されたかは確認できます。

この変換されたバイトコードをみるかぎり、Android O相当のAndroid SDKによってサポートされた「Java8の言語機能」はretrolambdaとほぼ同じです。

件のドキュメントの表にもあるとおり、 “Java8 Language API” つまりJava8の標準ライブラリ(stream, optional, etc.)を使うには依然としてAPI level 24が必要で、状況としては一年前のAndorid Nの時点とほぼ変わりません。

つまり、Android Oのpreviewが出ている現在でも、Java8に関して去年からの唯一のアップデートは、 retrolambda相当のツールがAndroid SDKに同梱されるようになった というだけということになります *1

Android Oで java.lang.invoke パッケージが追加されていたので、minSdkVersion = O ならもしかしたらinvokedynamicを使った本物のlambdaを使えるのではないかと思ったのですが、いまのところそのようにコンパイルされることは確認できませんでした。つまり、minSdkVersionの値に関わらず、desugarが必ず入るようです。このあたりはもしかしたら正規版までに変更があるかもしれませんが。

*1:去年の時点でβだったJackは正規版になるまえにdeprecatedになったのでノーカンで。