なみひらブログ

学んだことを日々記録する。~ since 2012/06/24 ~

Java9で追加される機能を少し見てみた話

背景

2017/03/23リリース予定(今のところ)のJava9の機能一覧をたまたま見かけたので、ちょっと確認してメモっときます。
※Java9はリリースが一回遅れていて、これ以上遅れないように幾つか削られるかも(;´Д`)

機能

気になったものを幾つか抜粋。順不同(;´Д`)

JEP 261: Module System

「Project Jigsaw」として開発されていたモジュール機構。
JEP的には他の番号も含めて、このモジュール機構を成している。コアの部分はこのJEP。
Java9の目玉機能。 世の中的に結構情報があるので詳細は割愛(;´Д`)←まだよく分かっていない。
自分の理解としては、

  • [これまで]全てのクラスをクラスパスでひとまとめで管理。
    • 依存モジュールが多くなってくる。クラスパス上に多くのクラスが存在する。(パッケージがあるから特に普段は問題ないけど。)
    • が、同じパスで違うバージョンのコード(クラス)が使えなかったりする。
  • [これから]モジュール単位(≒パッケージ単位)で依存クラスパスを指定できる。また参照される側が可視性も定義できる。

詳細は以下参照

www.slideshare.net

JEP 224: HTML5 Javadoc

HTML5対応したJavadocを出力できるオプションの追加。Javadocがもっとモダンになるかも(´Д`)

JEP 225: Javadoc Search

Javadocに検索窓追加。
いままで自分は言語仕様を調べるときは「list javadoc 8」とかでGoogle頼みの検索方法だったけど*1、1つのjavadoc内でサクサク移動できそう。
検索対象は「モジュール(?)」「パッケージ」「型」「メンバ変数」「メソッド名」あたり。javadoc全文検索というわけではない(;´Д`)
javadocで「@index hoge」とか定義して検索キーワードを追加できる。

JEP 269: Convenience Factory Methods for Collections

SetとかListとかMapとかのコレクション生成方法のためのAPI追加。ただし変更不可のコレクションの生成に限る。
(以下、上記リンク先の意訳)
これまでJavaは小さい変更不可のコレクションを作るのがめんどかった。

Set<String> set = new HashSet<>();
set.add("a");
set.add("b");
set.add("c");
set = Collections.unmodifiableSet(set);

とか

Set<String> set = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("a", "b", "c")));

とか

Set<String> set = Collections.unmodifiableSet(new HashSet<String>() {{
    add("a"); add("b"); add("c");
}});

とか

Set<String> set = Collections.unmodifiableSet(Stream.of("a", "b", "c").collect(toSet()));

これらが以下のようにできる

Set<String> set = Set.of("a", "b", "c");
List.of(a, b, c);
Set.of(d, e, f, g);

Mapは

Map.of()
Map.of(k1, v1)
Map.of(k1, v1, k2, v2)
Map.of(k1, v1, k2, v2, k3, v3)
...

Map.ofEntries(Map.Entry<K,V>...)

とか

Map.Entry<K,V> entry(K k, V v)

を使うと

Map.ofEntries(
    entry(k1, v1),
    entry(k2, v2),
    entry(k3, v3),
    // ...
    entry(kn, vn));

のように書ける。

JEP 277: Enhanced Deprecation

非推奨のクラス・メソッドにつける「@Deprecated」アノテーションの改善。
これまで、非推奨といっても「今後廃止されるから非推奨なのか(今後使えなくなる)、セキュリティ的に問題があるから非推奨なのか(今後も一応使える)」など非推奨の理由が曖昧で開発者が対応に困るので、表現力(since、forRemoval)を追加した。
昔みたときは、非推奨理由としてenum型で定義する予定だったが、それは主観が入り過ぎるので取り止めて(非推奨の理由詳細はjavadocに書く方針)、置き換えるべきかどうかのフラグだけにしたらしい。

Previous versions of this proposal included a variety of "reason" codes including UNSPECIFIED, DANGEROUS, OBSOLETE, SUPERSEDED, UNIMPLEMENTED, and EXPERIMENTAL. These attempted to encode the reason for which an API was deprecated, the risks of using it, and also whether a replacement API is available. In practice, all of this information is too subjective be encoded as values in an annotation. Instead, this information should be described in the Javadoc documentation comment. The only significant bit of detail remaining is whether there is intent to remove the API. This is expressed in the forRemoval annotation element.

定義の例:Java9から非推奨で、置き換えるべきメソッド

@Deprecated(since="9", forRemoval=true)
public String hoge() {
  ・・・
}

JEP 254: Compact Strings

ヒープメモリの多くはStringオブジェクトなんだけども、そのStringオブジェクトのメモリ確保の効率化。
メモリ使用量が減ると思われる。

JEP 241: Remove the jhat Tool

無くなる。1・2回使ったことある。

JEP 110: HTTP/2 Client

HTTP/2のためのHTTPクライアント追加。まだ利用する機会ないかも(;´Д`)

JEP 289: Deprecate the Applet API

1つの時代が終わる(;´Д`)

JEP 247: Compile for Older Platform Versions

「-source N -target N」の意味を兼ね備えた「-release N」の追加。

JEP 222: jshell: The Java Shell (Read-Eval-Print Loop)

「jshell」と呼ばれる対話型のJava実行ツールの追加。コンソール上でコード作成・実行できる。
ファイルでJavaコード書いて実行したほうが早いし確実?おそらく使わない(;´Д`)
※jrunscript(Nashorn)を使ってコンソールでコード実行したときと同じ印象(;´Д`)

その他

Stream APIのエンハンス

Java8で追加されたStream APIのエンハンスが無い(´・ω・`)

JEP 182: Policy for Retiring javac -source and -target Options

java9のコンパイラでJava5以前のコードがコンパイルできなくなる件、Java9のリストにない(´・ω・`)対応見送った?

まとめ

言語仕様的には軽微な変更(;´Д`)

*1:javadocにあるパッケージ一覧とかのリンク使っていない(;´Д`)