今更ながらJava11の新機能をまとめてみた

Posted by user on Sunday, September 1, 2019

TOC

背景

今までJava8の案件が主だったのですが、最近Java12の案件にも参画させて頂いています。

ただ、開発している中でJava9以降の機能を使っておらず、使える機能がないかを調べる目的でまとめてみました。
今回使用するサンプルコードは以下に全て置いてあります。
https://github.com/somurieengieer/javaSelfTraining/blob/master/src/sample/java11newFunc/Java11sample.java

追加された機能

String

isBlankの追加

isEmptyに加えて半角/全角スペースもtrueを返します。

(isEmptyは文字列の長さが0の場合のみtrueを返す)
※注意として、該当の変数がnullの場合はNullPointerExceptionを投げます。nullの場合もtrueを返してほしい場合はStringUtils.isEmpty()を使う必要があります。

String strBlank = "";
String strBlankChar = " ";
String strJapaneseBlankChar = " "; // 全角ブランク

// isBlankでは""、" "、" "の全てにおいてtrueを返す
if (strBlank.isBlank() &&
strBlankChar.isBlank() &&
strJapaneseBlankChar.isBlank()) {
    System.out.println("These are judged as Blank");
}

// isEmptyでは""のみtrueを返す
if (strBlank.isEmpty()) {
    System.out.println("These are judged as Empty");
}

// isEmptyでは""、" "の場合falseを返す
if (!strBlankChar.isEmpty() &&
!strJapaneseBlankChar.isEmpty()) {
    System.out.println("These are NOT judged as Blank");
}

Collection

toArrayの追加

Collection型のクラスにtoArrayメソッドが追加されました。メソッド名の通り配列に変換して値を返します。

String[] strs = List.of("aaa", "bbb").toArray(String[]::new);
for (String str : strs) {
    System.out.println(str);
}

// 引数なしのtoArrayだとObject[]を返す
Object[] objs = List.of("aaa", "bbb").toArray();

Optional

isEmptyの追加

isPresentの逆の値を返すメソッドとしてisEmptyメソッドが追加されました。

!を使わなくてもよくなりますね。

Optional<String> opt1 = Optional.ofNullable("hoge");
if (opt1.isEmpty()) {
    System.out.println("ここには到達しない");
}

Optional<String> opt2 = Optional.ofNullable(null);
if (opt2.isEmpty()) {
    System.out.println("optがnullの場合はここに到達する。isPresent()の逆条件");
}

Predicate

notの追加

Predicateで記述された条件結果の否定結果を返します。

notの引数はPredicate <? super T>、返り値はPredicateです。

var list = List.of("aaa", "bbb", "", "ddd");
list.stream().filter(Predicate.not(s -> s.isBlank()))
        .forEach(System.out::println);
// filterによってブランクでない"aaa", "bbb", "ddd"に絞られます

HTTP/2のサポート

HTTP/2に対応しました。java.net.http.HttpClientなどが追加され、単純な外部Webサーバへのアクセスは以下のようにやります。簡単です。

// クライアントを定義。プロキシ設定やhttpバージョンを指定できる。デフォルトでhttp2を使う
var client = HttpClient.newHttpClient();

// リクエストを定義。POSTパラメータやヘッダ設定などもここで行う
var request = HttpRequest.newBuilder(URI.create("https://www.google.com"))
.GET().build();
try {
    var response = client.send(request, HttpResponse.BodyHandlers.ofString());
    System.out.println(response.body().substring(0, 3000));
} catch (IOException e) {
    e.printStackTrace();
} catch (InterruptedException e) {
    e.printStackTrace();
}

単一Javaファイルの即時実行

単一のJavaファイルをコンパイルなしで即時実行できるようになりました。私はあまり使う機会はなさそうです。

具体的なコマンドは以下の通りです。

$ java HelloWorld.java    ←javacが不要。javaだけで実行できる
HelloWorld!

新しいガベージコレクション方式

ZGCという新しいガベージコレクションが追加。コンカレントGCであり、アプリケーションと平行して動作し、GCの停止時間を10ms以下にすることを目標に開発されているようです。

Linux/x64環境のみをサポートしています(Java13でLinux/A Arch64もサポートしそう)。
Java9でデフォルトGCがG1GCになりましたが、マシン性能が高い環境で動作することを前提とした仕組みになってきていますね。
ZGCの詳細は以下リンク先を参照ください。 https://wiki.openjdk.java.net/display/zgc/Main

Javaモニタリング機能の追加

FlightRecorderというモニタリング機能が追加されました。厳密には有償版には以前から存在していたようですが、無償版になったようです。

現時点で私は不要ですが頭の片隅に置いておいたほうが良さそうです。

所感

Java10に引き続き大きな仕様変更はありませんでした。

機能面は成熟度が増しており、複雑化する運用に対するサポート機能にも力を入れることができる状態にあるように感じました。
Java8以来のLTSになるため、Java9〜11の機能はセットで覚えておいても良さそうです。