KotlinConfに行ってJavaのことを思い出した話

punchdrunker
Jan 31 · 8 min read

こんにちは。ミクシィでみてねというアプリを開発しているpunchdrunkerです。昨年12月にKotlinConf 2019に参加したのと、直後にオフィスが引っ越したので、新オフィスでshibuya.apkのKotlinConf 参加報告会を開催しました。

自分も15枠で登壇したので、そのまとめ記事となります。

当日の資料

当日はライブ配信も行い、アーカイブ動画がYoutubeで公開されています。

What’s new in Java 19

肝心の中身ですが、今回お話した内容はJake Whartonによる、What’s new in Java 19というセッションを題材にJavaの最新動向についてお話ししました。

突然ですがAndroidアプリ開発者のみなさんに質問です。

2020年1月現在にリリースされているJavaの最新バージョンはいくつでしょうか?

(時計の針が進む音)

はい、答えはJava 13です。ちなみにJava 19は2022年あたりリリース予定のバージョンです。

KotlinConfなのにJava?という感じですが、このセッションがどういう内容だったかを先に説明します。

Q: Java19あたりで、いまKotlinにあるようなCoroutineやdata classなどの機能は大体揃ってくるけど、それでもKotlinって廃れない?

A: 3年後もJavaとKotlinはお互いに影響を与えあって進化し続けるよ

という話です。まあ、それだけだと味気ないので、今のJavaがどうなっているか、これからどうなるか、Androidではどうなるのか、という展望をざっくり紹介しました。

Javaの近況

普段KotlinでAndroidアプリの開発しているとJavaの最新動向はあまりキャッチアップしていない人が多いのではないでしょうか?

自分もその一人で、当日のトーク以外にもJake Whartonがここ1年ブログに書いているD8 and R8 seriesをいくつか読み、Javaの近況や、JavaがどのようにAndroidで動くようになっているかなどを調べました。

ちなみに、そろそろKotlinでしかAndroidアプリを作ったことが無い人がいるのでは?と思い当日アンケートを取ったところ、1人だけいたので、時代の変化を感じました。

Java9〜13の新機能

さて、まずはすでにリリースされているJavaの新機能を紹介します。私達がAndroid開発で使えるJavaは8なので、現状Android開発には使えない機能です。

  • 文字列連結(String同士の+)をしてもStringBuilderが使われなくなる
  • var の導入
  • Nestmates(innerクラスから親クラスへのprivate fileld参照で合成アクセサが出来ないようになる)
  • switch式(switchで値を返せる)
  • multiline string(ヒアドキュメント)

バイトコードでの比較

バイトコードレベルの機能もあるので、shibuya.apk当日の発表ではJava8とJava 13で単純なコードをコンパイルした結果をjavapで逆アセしたものを見比べました。Java 13のバイトコードは確かにすっきりしていました。

これがサンプルコードです。文字列連結と

Java8でのバイトコードの様子(逆アセ結果)がこちらです。クラスごとにclassファイルが生成されますが、これはInnerクラスの方。

図示した通り、コードには書いてないけど、裏でStringBuilderが使われたり、getterが増えていることがわかります。

これらがJava 13で改善されていることがわかります。

ネイティブの命令が実行されるように変わりました。そして上述のコードをKotlinで書いたとしても、結果は同じです。

Java 14以降に予定されている新機能

ここからはさらに今後リリースされる予定の機能です

  • records (Kotlinで言う data class)
  • sealed interface
  • Virtual threads(Coroutine相当のことができる)

なるほど、ほぼKotlinでできてることがJavaだけでも出来そうという事がわかりました。

AndroidとJava 8、と見せかせて実はJava7

ここからがshibuya.apkぽい話になりますが、Androidアプリとしてビルドされる工程の中で、私達が書いたコードは色々な形でコンパイル、最適化されます。大雑把に説明すると以下のような事がアプリのビルド時に起こります。

  • Java8 VMで動くバイトコードが生成される(Kotlinで書こうがJavaで書こうが一緒)
  • D8によりdesugarされ、Java7のVMで動くのバイトコードが生成される
  • R8によりバイトコード最適化(shirink/minify)
  • dexファイルが生成される
  • apkが生成される

いま大体のアプリがminSdkVersionが21(Android 5)や23だと思いますが、23(Android 6)まではJava 7でしか動きません。Java 8対応したのはAndroid 7(API 24)からです。

Java8の代表的な新機能でLambdaが有名ですが、普段私達がJavaでlambdaとして書いたものが動いているのは、その裏でD8がJava 7表現に変換(desugar)してくれているおかげです。

Java 8以降のLong Term Support(本命バージョン)は11とか17ですが、将来Androidがそれらのバージョンに対応したとしてもminSdkVersionが29(Android 10)とかであれば、D8でdesugar(Java 11のコードをJava 8の表現に変換)できるようになっていないと製品投入できないわけです。

そして話がさらに複雑になるので敢えて省略しましたが、厳密にはAndroidのVMはOracleが出しているJVMではなく、Android4系まではDalvik、 5以降ではARTというVMが採用されています。Androidの文脈でVMと書いてある箇所はJava {7, 8}相当の{Dalvik, ART} を指します。

いつAndroidでJava 9以降が使えるか

今後どのようなプランでAndroidが新しいJavaに対応していくかは明らかになっていませんが、先の話でしょう。ただ新しいOSで対応するだけではなくて、Java 8 VMでも動くように互換を持たせるためのdesugarする仕組みもセットで必要だからです。

かつて2014年頃(Android 5が最新時代)に、「AndrodでJava 8対応してくれればLambda使えるのにねぇ」、とみんなが切望していた記憶がありますが、6年たった今ではあたり前に使えるものになりましたし、Kotlinもスタンダードになり、IDEも進化して、どんどん開発が楽になってきました。これからもAndroidの進化に期待したいと思います。

当日のサプライズ

また、当日は元ミクシィのkyoroさんが「エンジニアだけど米国でワイナリーを買った話」で話題になったSunset Cellarsのワインも提供しました。

左からAfterglow, Barbera, Crescent moon

ワインについては主に自分が味の説明などをしながらサーブしましたが、とても好評でした。Javaだけでなく、こちらのワインも今後のリリースに期待。

みてねではエンジニア採用しています

採用情報もみてね

mixi developers

ミクシィグループのエンジニアやデザイナーによるブログです。

punchdrunker

Written by

Programmer in Tokyo. mixi, inc / DroidKaigi / Shibuya.apk

mixi developers

ミクシィグループのエンジニアやデザイナーによるブログです。

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade