torutkのブログ

ソフトウェア・エンジニアのブログ

Java SE 9リリースのニュース記事で気になった互換性について

米国時間で9月21日、日本では9月22日の早朝、Java SE 9がリリースされました。

リリースのニュースがいくつか流れていますが、その中で次の記事にちょっと気になる表現がありました。
[速報]Java 9が正式リリース、Javaをモジュール化するProject Jigsawがついに実現。今後のJavaは6カ月ごとタイムベースのアップデートへ - Publickey

一方でJava 9は日付や通貨のデフォルトフォーマットが変更され、いくつかの構文や演算子の変更や廃止が行われるなど、Java 8以前との互換性は保証されていません。Java 9への移行へは十分な調査などを行うべきでしょう。

「互換性は保証されていません」という表現は煽情的な表現*1ですが、ではどのような互換性のなさがあるのかを調べてみたいと思います。

Java SE 9で互換性が失われる変更点

OracleJDK 9ドキュメントの一つ、「Java Platform, Standard Edition Oracle JDK 9 Migration Guide」から、互換性(後方互換性)が保たれない変更点をピックアップしてみます。
http://docs.oracle.com/javase/9/migrate/toc.htm

ソースコード記述に関する変更点
  • アンダースコア単一文字の識別子を使用していた場合、JDK 9からはコンパイルエラーとなる

言語仕様上は、後方互換性が保たれない変更点はこれだけかと思います。
互換性のある変更点を含めた一覧が次にあります。
https://docs.oracle.com/javase/9/language/toc.htm

冒頭で参照したニュース記事の「いくつかの構文や演算子の変更や廃止」という表現について、「廃止」に該当するのはアンダースコア単一文字の識別子の使用の1点で、その他の構文・演算子の変更は互換性を保った変更であると思います。

  • javacのオプションで-sourceおよび-targetオプションで5以下を指定した場合、コンパイルエラーとなる

これは前方互換性として、JDKコンパイラが古い3バージョンまでを対象としているからですね。JDK 9からそれより古い3バージョンだと、2006年にリリースされたJava SE 6までを対象としています。

  • sun.miscなどの非公開APIを使用していた場合、ごく一部(sun.misc.Unsafeなど)を除いてコンパイルエラーとなる

JDK 9のリリースノートに、削除されたAPI、機能、オプションが記載されています。
http://www.oracle.com/technetwork/java/javase/9-removed-features-3745614.html

これは、今までは逆に公開APIでなくても互換性を維持し続けていたという点で凄いのかなと思います。

  • deprecate(非推奨)指定されたメソッドが増えている(コンパイル時は警告として指摘)
  • リフレクションについて(後日調べる)
ライブラリ(JARファイル)構成の変更点

Java SE 9 の目玉であるモジュール化によって、ライブラリ構成が大きく変化しています。
JDK/JREについては、ディレクトリ構造、ランタイムのJARファイル構成に変更があります。
ごく普通にJavaプログラムを書いているときはランタイムのJARファイル名を意識する必要はありませんが、例えば、rt.jarやtools.jarをファイル名で参照するような作り(起動スクリプトやプログラム中で参照するなど)をしていると、Java SE 9では変更が必要になります。

モジュール化については、これからじっくり調べて学習していきます。

*1:この言い方では、今回のバージョンアップは互換性が大いにないと受け取る人が続出しそうです。変更点を見る限りでは、「100%の互換性は保証されていません」であるとか、「互換性が必ずしも完全ではありません」といった言い方が実情に近いと思います。