Java8からJava21までの進化点をピックアップしてみた
Java8がGAしてから10年ほど経ちましたが、その間にJava8は開発現場に広く浸透してきました。
しかし、サポート期限の終わりも見えてきたのと、あとの世代のJavaのLTSのバージョンもリリースされてきて、より新しいLTSが開発現場に使われるようになってきていると思います。
この記事では、Java21までの言語仕様の変化をピックアップして簡単におさらいできればと思います。
varによる型推論(Java 10)
Java 8では、ローカル変数の宣言には必ず型を書く必要がありました。例えば次のように:
List<String> names = new ArrayList<>();
Java 10からはvarキーワードが導入され、型が明らかな場合に限って、型の明示を省略できるようになりました。
var names = new ArrayList<String>();
このように書くことで、冗長なコードを減らすことができ、特に型名が長くなりがちなジェネリクスの初期化では有効です。ただし、varは型を隠すのではなく、読みやすさを損なわない範囲での省略にとどめるのが最も可読性が向上すると思います。固定値での初期化時など、明らかに読んで分かる場合に使うと良いです。
どう転んでも可読性が下がるといった意見もありましたが、KotlinやScala、およびTypeScriptやGoなど普及が進んでいる他言語ではこのような型推論機能が受け入れられており、にも関わらずJavaでは使わない方がいいと判断するのはいささか早計だと思います。
スイッチ式(Java 14で正式)
Java 8までのswitchは文(statement)であり、値を返すような使い方はできませんでした。また、各caseでbreakを書くのが忘れられがちで、これがバグの原因になりやすいという問題もありました。
Java 14でswitch式が正式に導入され、より安全かつ柔軟に使えるようになりました。
enum WD {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
var day = WD.MONDAY;
String result = switch (day) {
case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> "Weekday";
case SATURDAY, SUNDAY -> "Weekend";
};
- ->構文により、明確な分岐が記述できる
- 式として値を返せるため、switchの用途が広がる
といったメリットがあります。
従来の文ベースのswitchも引き続き使用できますが、新しい構文に切り替えることでバグの入りにくいコードが書けるようになります。
パターンマッチング(instanceofの進化, Java 16〜)
Java 16では、instanceofをより使いやすくするためのパターンマッチングが導入されました。以前のようにキャストのために冗長なコードを書く必要がなくなりました。
Java 8では:
Object obj = "AAA";
if (obj instanceof String) {
String s = (String) obj;
System.out.println(s.length());
}
Java 16以降では:
Object obj = "AAA";
if (obj instanceof String s) {
System.out.println(s.length());
}
この構文は、型チェックとキャストを同時に行うもので、スッキリとしたコードが書けるようになります。今後さらに、switch文との組み合わせによる高度なパターンマッチング(Java 21ではプレビュー)も進化中です。
レコード(Java 14でプレビュー、Java 16で正式)
データクラスを定義するのに、Java 8ではフィールド、コンストラクタ、getter、equals、hashCode、toStringを全て自分で実装する必要がありました。
Java 16から正式に導入されたレコード(record)は、そのような不変データキャリアの定義を圧倒的に簡潔にします。
record Person(String name, int age) {}
これだけで、以下を自動的に生成してくれます:
- コンストラクタ
- getter(name()、age())
- equals / hashCode
- toString
レコードは イミュータブル(不変) な設計が基本となっており、スレッドセーフなコードや値オブジェクトの設計にも向いています。
一部の値を書き換えて複製する機能はまだプレビューのようなので、そこが正式サポートされるとますます使い勝手が良くなりそうです。
他にも、 Sealedクラス
Project Jigsaw
テキストブロック
などありますが、またの機会に紹介します。
まとめ
Java 8以降、Javaはより表現力が高く、モダンな言語へと進化を遂げています。varやswitch式、パターンマッチング、レコードのような新機能は、保守性・可読性の高いコードを書くための強力な武器となります。
Java 21ではこれらが安定的に使えるLTSとしてリリースされており、今後の開発でも主力になっていくでしょう。サポート期限も2031年9月までが予定されています。もしまだJava 8を使っているプロジェクトがあれば、そろそろ移行の検討を始めてみても良いかもしれません。
Discussion