Java 11 の新機能

JavaBeginner

はじめに

Java 11 は 2018 年 9 月にリリースされ、このプラットフォームに多くの新機能と変更が導入されました。この実験では、Java 11 を始める手順と新機能の探索方法を案内します。

環境の設定

まず、システムに JDK 11 がインストールされていることを確認します。ターミナルで次のコマンドを実行することで確認できます。

java -version

Java 11 がインストールされていない場合は、Oracle のウェブサイトからダウンロードするか、apt-get や yum のようなパッケージマネージャを使用できます。

JDK のセットアップが完了したら、次のコマンドで Java ファイルを作成します。

mkdir -p ~/project && cd ~/project
touch MyFirstJavaProgram.java

これで Java ファイルが作成されたので、好きなテキストエディタで開きます。

touch MyFirstJavaProgram.java

Java ファイルの実行

Java 11 以前は、javac コマンドを使って Java ファイルをコンパイルし、その後 java コマンドを使って実行する必要がありました。Java 11 では、java コマンドだけを使って直接 Java ファイルを実行できます。

MyFirstJavaProgram.java ファイルに次のコードを追加します。

public class MyFirstJavaProgram {
    public static void main(String[] args) {
        System.out.println("Hello, Java 11!");
    }
}

ファイルを保存し、次のコマンドを使って実行します。

java MyFirstJavaProgram.java

コンソールに "Hello, Java 11!" が表示されるはずです。

新しい String メソッド

Java 11 は String クラスにいくつかの新しいメソッドを導入しました。このステップでは、それらの新しいメソッドを調べます。

isBlank() メソッド

isBlank() メソッドは、文字列が空白かどうかをチェックするために使用されます。空の文字列または空白のみの文字列は空白と見なされます。

MyFirstJavaProgram.java ファイルに次のコードを追加します。

String s1 = "";
String s2 = "    ";
String s3 = "String";

System.out.println("s1 is blank: " + s1.isBlank());
System.out.println("s2 is blank: " + s2.isBlank());
System.out.println("s3 is blank: " + s3.isBlank());

ファイルを保存し、次のコマンドを使って実行します。

javac MyFirstJavaProgram.java
java MyFirstJavaProgram

次の出力が表示されるはずです。

s1 is blank: true
s2 is blank: true
s3 is blank: false
strip()、stripLeading()、および stripTrailing() メソッド

strip()stripLeading()、および stripTrailing() メソッドは、文字列から空白を削除するために使用されます。既存の trim() メソッドと似ていますが、Unicode のサポートを提供します。

MyFirstJavaProgram.java ファイルに次のコードを追加します。

String s = "   String   ";
System.out.println("$" + s + "$");
System.out.println("$" + s.strip() + "$");
System.out.println("$" + s.stripLeading() + "$");
System.out.println("$" + s.stripTrailing() + "$");

ファイルを保存し、次のコマンドを使って実行します。

javac MyFirstJavaProgram.java
java MyFirstJavaProgram

次の出力が表示されるはずです。

$   String   $
$String$
$String   $
$   String$

ネストベースのアクセス制御

Java 11 は、リフレクション API を使用してネストされたクラスのプライベートメンバにアクセスできる新機能を導入しました。このステップでは、この新機能を調べます。

MyFirstJavaProgram.java ファイルに次のコードを追加します。

public class Demo {
    private void privateMethod() {
        System.out.print("Private Method");
    }
    class NestedClass {
        public void callPrivateMethod() {
            privateMethod();
        }
    }
    public static void main(String[] args) {
        System.out.println(Demo.class.isNestmateOf(Demo.NestedClass.class));
        System.out.println(Demo.NestedClass.class.isNestmateOf(Demo.class));
        System.out.println(Demo.NestedClass.class.getNestHost());
        System.out.println(Arrays.toString(Demo.class.getNestMembers()));
    }
}

ファイルを保存し、次のコマンドを使って実行します。

javac MyFirstJavaProgram.java
java MyFirstJavaProgram

次の出力が表示されるはずです。

true
true
class Demo
[class MyFirstJavaProgram$Demo$NestedClass]

新しいファイルメソッド

Java 11 は、文字列の読み書きを簡単にするための Files クラスにいくつかの新しいメソッドを導入しました。このステップでは、これらの新しいメソッドを調べます。

MyFirstJavaProgram.java ファイルに次のコードを追加します。

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class Demo {
    public static void main(String[] args) throws IOException {
        Path path = Files.createTempFile("temporaryFile", ".txt");
        //Writing to the file
        Files.writeString(path, "Hello World");
        //Reading from the file
        String s = Files.readString(path);
        System.out.print(s);
    }
}

ファイルを保存し、次のコマンドを使って実行します。

javac MyFirstJavaProgram.java
java MyFirstJavaProgram

次の出力が表示されるはずです。

Hello World

コレクションを配列に変換する

Java 11 は、コレクションを正しい型の配列に変換するのを簡単にする新しいデフォルトの toArray() メソッドを導入しました。

MyFirstJavaProgram.java ファイルに次のコードを追加します。

import java.util.ArrayList;
import java.util.Arrays;

public class Demo {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(5);
        list.add(10);
        list.add(15);

        Integer[] intArr = list.toArray(Integer[]::new);
        System.out.print(Arrays.toString(intArr));
    }
}

ファイルを保存し、次のコマンドを使って実行します。

javac MyFirstJavaProgram.java
java MyFirstJavaProgram

次の出力が表示されるはずです。

[5, 10, 15]

not() メソッド

Java 11 は、述語を否定するために Predicate インターフェイスに新しい not() メソッドを導入しました。このステップでは、この機能を調べます。

MyFirstJavaProgram.java ファイルに次のコードを追加します。

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class Demo {
    public static void main(String[] args) {
        Predicate<String> startWithZ = s -> s.charAt(0) == 'z';
        Predicate<String> doesNotStartWithZ = Predicate.not(startWithZ);

        List<String> list = Arrays.asList("za", "zq", "az", "aq", "zz");
        List<String> strsStartingWithZ = list.stream()
             .filter(startWithZ)
             .collect(Collectors.toList());
        List<String> strsNotStartingWithZ = list.stream()
             .filter(doesNotStartWithZ)
             .collect(Collectors.toList());

        System.out.println(strsStartingWithZ);
        System.out.println(strsNotStartingWithZ);
    }
}

ファイルを保存し、次のコマンドを使って実行します。

javac MyFirstJavaProgram.java
java MyFirstJavaProgram

次の出力が表示されるはずです。

[za, zq, zz]
[az, aq]

HTTP クライアント

HTTP クライアント API は Java 9 で導入され、Java 11 で標準化されました。このステップでは、新しい HTTP クライアント API をどのように使用するかを調べます。

MyFirstJavaProgram.java ファイルに次のコードを追加します。

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;

public class Demo {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
             .uri(new URI("https://www.google.com"))
             .GET()
             .build();
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
        System.out.println(response.body());
    }
}

ファイルを保存し、次のコマンドを使って実行します。

javac MyFirstJavaProgram.java
java MyFirstJavaProgram

コンソールに Google のホームページの HTML コードが表示されるはずです。

ラムダのローカル変数構文

Java 11 は、ラムダ式にローカル変数構文を使用できるようにするために var キーワードを導入しました。このステップでは、この新機能を調べます。

MyFirstJavaProgram.java ファイルに次のコードを追加します。

import java.util.function.Predicate;

public class Demo {
    public static void main(String[] args) {
        Predicate<String> startsWithZ = (@NotNull var str) -> str.charAt(0) == 'z';
        System.out.println(startsWithZ.test("zoo"));
    }
}

ファイルを保存し、次のコマンドを使って実行します。

javac MyFirstJavaProgram.java
java MyFirstJavaProgram

コンソールに true が表示されるはずです。

エプシロンガーベッジコレクタ

Java 11 は、メモリを割り当てるだけでガーベッジコレクションを行わない新しい実験的機能であるエプシロンガーベッジコレクタを導入しました。このステップでは、この実験的機能を調べます。

MyFirstJavaProgram.java ファイルに次のコードを追加します。

public class Demo {
    public static void main(String[] args) {
        byte[] b = new byte[1024 * 1024 * 1024];
        System.out.println("Allocated 1GB of memory");
    }
}

ファイルを保存し、次のコマンドを使って実行します。

java -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC MyFirstJavaProgram.java

コンソールに "Allocated 1GB of memory" が表示され、その後、コード 0 でプログラムが終了するはずです。

まとめ

この実験では、Java 11 に導入された新機能について学びました。新しい String メソッド、ネストベースのアクセス制御、新しいファイルメソッドなどが挙げられます。また、新しい HTTP クライアント API とエプシロンガーベッジコレクタの使い方も学びました。これで、Java 11 とその機能についてより深く理解できるようになったはずです。