読者の皆様へ: 皆様のご要望にお応えするべく、ノイズを削減する機能セットを開発しました。皆様が関心をお持ちのトピックを、EメールとWeb通知で受け取ることができます。新機能をぜひお試しください。
GAリリース予定を2018年3月20日に控えて、Java 10 RC 1がJavaコミュニティに向けて公開された。今回のリリースは、Oracleの新たな6ヶ月リリースサイクルによる最初のアップグレードになる。今月初めには、Java 10 (18.3) (JEP 383)の提案済み最終草案が公開されている。その提案スケジュールによれば、間もなくリリース候補のフェーズに入るはずだ。
リリース候補の資料には、具体的な目標として次のものが挙げられている。
- JDK 10で新たに発生したP1バグと、リリースの成功に必要な重要バグはすべてフィックスする。
- JDK 10で発生したもの以外で、今回のリリースを対象としていたが、今回のリリースでは重要でないP1バグについては修正の対象外とする。
- JDK 10で新たに発生したバグの中で、今回のリリースでは重要でないか、あるいは妥当な理由があって修正できないバグについては、意図的に延期する。
P2からP5に分類されたバグについては、製品コード、テスト、資料の状態に関わらず、今後のリリースでの対応とされている。
11月にInfoQがお伝えしたように、Java 10の新機能の一部はすでに開発が終了している。開発者が期待できるのは以下のものだ。
- JEP-286:ローカル変数の型推論
- JEP-296: JDK Forestの単一リポジトリへの統合
- JEP-304: ガベージコレクタインタフェース
- JEP-307: G1フルGCの並列化
- JEP-310: アプリケーションクラスデータ共有
- JEP-312: スレッドローカルハンドシェイク
- JEP-313: ネイティブヘッダ生成ツール(javah)の廃止
- JEP-314: Unicode言語タグ拡張の追加
- JEP-316: 代替メモリデバイスへのヒープ割り当て
- JEP-317: 実験的なJavaベースJITコンパイラ
- JEP-319: ルート証明書
- JEP-322: 時間ベースのリリースバージョン管理
JEP-286: ローカル変数の型推論
Java 10で最も関心と期待を集めている機能は、新たな予約型var
の導入によるローカル変数の型推論だ。これによって以下のようなコードの記述が可能になる。
var x = 10;
var y = 20;
var z = application.getSum(x,y);
public int getSum(int x,int y) {
return x + y;
}
var list = new ArrayList<String>();
list.add("Hello!");
list.add("World!"
var
が使用できるのは次の場合に限られる。
- 初期値を持つローカル変数
- forループのインデックス
- 条件付きループのローカルスコープ
パラメータリストや戻り値の型としてvar
を使用することはできない。従って、以下のコードはコンパイルされない。
public int passByVar(var y) {
return y;
}
public var returnVar(int y) {
return y;
}
この他にも、多くのコード例がGitHubで公開されている。
Oracleが2016年初めに実施した2件の調査の結果によると、開発者はローカル変数の型推論の導入について肯定的である。しかしながら、その調査報告でも議論されているように、懸念されるのは可読性だ。
何人かのコメント寄稿者が、次のようなコードを例として挙げていました。
var x = y.getFoo()
“この例では’x’が何であるか分からず、可読性がない”という指摘です。しかしながら、ここで問題になる可読性は、’x’という変数名の選択が不適切である、という事実によるものです。明確な型定義がプログラマの怠惰を補ってくれるかも知れませんが、まずは適切な変数名を選ぶことが大切でしょう。
状況はさまざまかも知れませんが、この機能を丁寧に記述されたコードで適切に使用することで、可読性は確実に“向上”すると信じています。次のようなローカル変数のブロックを考えてみましょう。
UserModelHandle userDB = broker.findUserDB(); List<User> users = db.getUsers(); Map<User,Address> addressesByUser = db.getAddresses();
それぞれの行で最も重要なのは何でしょう、変数*名*でしょうか、変数*型*でしょうか、あるいは初期化式でしょうか?私たちは名前だと思います - *プログラムのこの部分*で、変数の役割を説明したものだからです。ただし、このコードでは、変数名を視覚的に見つけ出すのはそれほど簡単ではありません -- 各行の中間にあって、行毎に位置が違っているからです。
読む側の視点で最も重要なことは、行の先頭と中央に配置できると理想的です。上記のブロックを型推論で書き直せば、次のようになります。
var userDB = broker.findUserDB(); var users = db.getUsers(); var addressesByUser = db.getAddresses();
このコードの本当の意図がはるかに明確になっています - 変数名が(ほぼ)先頭と中央にあるからです。適切な変数名を選択すれば、明確な型定義の欠如は問題にはなりません。
ガベージコレクションの改善
InfoQで既報のように、JEP-304では、新しいガベージコレクタインタフェースが導入される。
ベンダにとっては、特定のGCアルゴリズムを含んだ、あるいは除外したJDKビルドの作成が容易になるはずだ。Shenandoah、ZGC、開発中のEpsilonといった新たなGCアプローチにとって、これは理に適った方法だ。コミュニティの中にはコンカレント-マーク-スイープコレクタ(CMS)を非推奨にしたり、さらには削除しようとする動きもあるが、現時点では、それを実現するための製品レベルの代替品は存在しない。
JEP-307は、シングルスレッドのアルゴリズムを使用していたJava 9までのG1ガベージコレクタの問題を解決するものだ。InfoQでも取り上げている。
これはつまり、G1がフルGCにフォールバックしなければならない場合には、パフォーマンス上の大きな問題が待ち受けているということになる。JEP 307の目的は、フルGCアルゴリズムを並列化することによって、万が一G1フルGCが発生した場合でも、並列GCと同じ数のスレッドを利用可能にすることにある。
削除された機能
javah
ユーティリティが公式に廃止された。理由については、JEP-313に説明されている。
本ツールは、JDK 8で追加された
javac
の上位機能(JDK-7150368)によって置き換えられました。この機能では、Javaソースコードのコンパイル時にネイティブヘッダファイルを作成できるため、別ツールの必要はなくなっています。
javac
の提供するサポートに重点を置くことで、javax.tools.*
のコンパイラAPIを通じたAPIアクセスや、JDK 9で新たに追加されたjava.util.spiToolProvider
SPIのような、新たなパラダイムをサポートするためにjavah
をアップグレードする必要はなくなります。
Oracleのテクニカルスタッフの重要メンバであるMandy Chung氏は先日、Java 1.2から非推奨とされていたRuntime.runFinalizersOnExit()
とSystem.runFinalizersOnExit()
の2メソッドについて、最終的にJDK 11で削除する提案をOpenJDKに提出した。これらのメソッドは、生存中のオブジェクトのファイナライザを呼び出す際に、別のスレッドがそのオブジェクトに対して並列的に行っている操作が不安定化ないしデッドロックする可能性があるため、安全でないと考えられている。
新機能と廃止機能はすべて、リリースノートにその詳細が説明されている。
リソース
- Java to Move to 6-Monthly Release Cadence(Javaのリリースは6ヶ月ごととなる)、InfoQ (2017年9月6日)
- Java 10 Sneak Peek: Local-Variable Type Inference (var)! 、Adrian Finlay (2017年11月14日)
- Java 10 - The Story So Far(Java 10 - これまでの経緯) by InfoQ (2017年11月21日)
- Inspired by Actual Events、Dustin Marx (2018年2月1日)
この記事を評価
- 編集者評
- 編集長アクション