日々常々

ふつうのプログラマがあたりまえにしたいこと。

Java17雑感

LTSとなるJava17が出ました。組織が今後もJavaを使っていけるかの試金石になるバージョンだと思います。

実際のとこLTSだから特別安定してるとかそんなことはないと思うし、6バージョン(3年)ごとにLTSにするってのもたぶんOracleさんが言ってみただけで、いろんなとこがそれに乗っかってるから、実質的に節目になってるに過ぎない。はず。 その程度のものなんだけど、私のようなのは乗っかりますし、たぶん多数派なんじゃないかなぁ……この派閥が運用で使うJavaのバージョンは8、11、17で、他のバージョンは評価に使うくらいでしょう。

11から17のジャンプになるんで、かなりたくさんの変更がありますが、業務アプリケーションの表層に関係するものはそこまで多くありません。パフォーマンスとかに影響のあるものは多々ありますが、基本的には早くなるはずで、問題になることは稀です。稀なことはよくあるんですが。

ということで、17にした時に業務アプリケーションの表層に影響のありそうなものを挙げて雑感を書いておきます。多分3ヶ月後くらいにはいうこと変わりますが。 JEPの名前とリンク、正式版として導入されたバージョンです。

  • Text Block: JEP 378, Java15
    • 複数行文字列が書けるようになります。
    • テストコードでJSONを書くときにエスケープしなくて良くなるのが嬉しいです。
    • プロダクトコードで巨大な文字列を扱う場合はテンプレートエンジンを使うと思うのであまり出番はないはずです。
    • あるとしたらSQL。JdbcTemplateやMyBatisのアノテーションなど、SQLJavaコードに交えて書くのが楽になる気はします。
  • Switch Expression: JEP 361, Java14
    • switch式です。 if式が欲しい
    • なんかswitchの強化多いんですよね。11以前はswitchなんて滅多に使わなかったけど、今後は見る機会が増えてくるかもしれません。
    • とはいえ無理に使わなくてもいいと思います。いい感じに書けそうなら試す、くらいで。
  • Record: JEP 395, Java16
    • 目玉。Java17を採用するなら使っていきたいかなーと。
    • 私がよく見る「lombokを使いたい動機」のほとんどが消えます。Data以外にBuilderとか使い倒してたら引き続き出番はありますが。
    • イミュータブルの強要、アクセサのメソッド名にgetがつかない、バインディングライブラリの対応状況など、地味なハードルはあります。
    • とは言え無理に使わなくてもいいと思います。recordでなければできないことも今はないだろし。
    • 2021-09-24追記: Recordを使ってく上で気にしとくこと 書いた。
  • Sealed Class: JEP 409, Java17
    • 他言語によく(?)あるSealedClassがJavaにもやって来ました。
    • 挙げてはみたものの、今後の準備として入った程度の認識で良いかと。
    • 使い方がこなれて、これを利用するものが増えてきてからでいいと思います。
  • Pattern Matching for instanceof: JEP 394, Java16
    • instanceofの後のキャストを書かなくて良くなります。
    • ジェネリクス以降登場機会の激減したキャストさんの活躍場所がまた減った。
    • 挙げてはみたものの、そもそもinstanceofを使う機会が少ないし、無理に使う必要は無いかと。
    • 使える場面では喜んで使えばいいと思います。一行減るだけだけど。

五つだけ。まとめると「TextBlockをテストで使って、データクラスを新しく作るならRecordを使ってみる」くらいでしょうかねぇ。

コーディングにそう影響ないから挙げてないけど、個人的に一番嬉しいのはHelpful NullPointerExceptionsだったりします。下手にnullチェックして例外投げるくらいなら、チェックせずそのままNPE発生させる方が役立つ可能性まである気がしてたり。

細かいけど嬉しいの

  • String#formatted Java12
  • Stream#toList Java16
  • Collectors#teeing Java12

ちょっと便利系。この辺のAPIIDEが教えてくれるから、存在自体を知らなくても、使う機会が来たら使えると思います。

実際いつあげんの

  • プロダクトはSpringBootがほとんどなんで、来週出るらしいJava17対応のSpringBoot2.5.5に乗っかる。
  • その頃にはbuildpackも出るだろから乗っかってないのもいけるかなって。
  • Java16で動かしてるものは軽い気持ちでコンパイルから全部17にあげる。
  • Java11のは検証環境のランタイムだけ17にしてしばらく回してから。

そんな感じ。

まともな情報