Javaコラム Javaエンジニアのためのお役立ちコラム

Java8からJava 11の変わったところを紹介!|Java 11の様々な改良を知ろう

2021年02月24日
SE
Java 8からJava 11へバージョンアップするとどのような変化があるのでしょうか。
PM
型推論などができるようになります。詳細は順に説明していますので、一緒に見ていきましょう。

Java 11とは?

Java 11について知る前に、Javaの歴史に簡単に触れておく必要があります。

Javaは、元々フリーで自由に使えるプログラミング言語でしたが、Java 8からは商用と個人用に分かれました。そして長期サポートを受けられるのはJava 8の商用版だけとなったのです。

その後のJava 9、Java 10は半年間だけの短期サポートなり、Java 11で二度目の長期サポート版が出ました。次の長期サポート版はまだリリースされてないJava 17の予定なので、現時点で正式版として利用できるJavaは8と11だけと言えます。

この記事ではJava 11が8からどう変わったかについて解説しましょう。

型推論が使えるようになった

Java 11ではvarにより型推論ができるようになっています。型推論とは変数の型を宣言せずに様々な型の変数を扱える機能です。以下のように、基本型でもクラス型でもvarとして宣言できます。

var intValue = 100;
var stringValue = “”文字列””;
var arrayValue = new java.util.ArrayList();

注意すべき点は、var型なら常にどのような値も扱えるわけではなく、宣言で代入する時点でvarの中身の型は決まってしまい、その後は宣言の時に決まった型でしか使えません。

varでわかりにくくなるケースでは使用を避ける

var型にint型の数値を代入して宣言した場合、その変数はint型になっているのでしょうか。調べるには以下のようにします。

var intValue = 100;
Object obj = intValue;
System.out.println(obj.getClass());

実行すると、

class java.lang.Integer

と表示されます。int型をラップするIntegerクラスになっていました。このvar型の変数に以下のようにするとコンパイルエラーがでますが、 以下なら大丈夫です。 また、NullPointerExceptionが発生します。

intValue = null;

以下なら大丈夫です。varでは変数の実体の型が分かりにくくなって困るようなケースでは使用しない方が良いでしょう。

intValue = (Integer) null;

interfaceにprivateメソッドを導入

Java 11ではinterfaceにprivateなメソッドを宣言できます。しかしinterfaceは、privateなので外部からオーバーライドできないメソッドは意味があるのでしょうか?まず以下のサンプルを見てください。

interface TestInterface {

public default void work() {
dispMessage();
}

static void statWork() {
statDispMessage();
}

private void dispMessage () {
System.out.println(“”動的なメッセージです。””);
}

private static void statDispMessage () {
System.out.println(“”静的なメッセージです。””);
}
}

public class MainClass implements TestInterface {

public static void main(String[] args) {
TestInterface.statWork();

MainClass mc = new MainClass();
mc.work();
}
}

default処理やstaticの処理でprivateメソッドを活用できる

上のサンプルを実行すると、以下のように表示されます。

静的なメッセージです。
動的なメッセージです。

Javaは8の時点で、メソッドにdefaultを宣言することにより、そのメソッドがオーバーライドされなかった場合の時の、デフォルト処理を記述できるようになっています。またstaticなメソッドでも処理を記述できます。

ただし、1つのメソッド内に長い処理を書きたくなかったり、共通で使えるメソッドが欲しい時があります。その場合、interfaceの記述内で呼び出すためのprivateメソッドを使えるようになったということです。

try-with-resource文の改良

Javaにはtry-with-resourceという自動的にCloseしてくれる機能がありますが、Java 11で改良されました。従来までは以下のようにtry節では変数の代入の記述が必須だったため、別の変数に入れる必要がありました。

public static void main(String[] args) throws Exception {
File f = new File(“”c:\\test\\test.txt””);
FileWriter fw = new FileWriter(f);
try (FileWriter fw2 = fw) { // 別の変数に入れなければならない
fw2.write(“”あいうえお””);
} catch (IOException e) {
e.printStackTrace();
}
}

Java 11からは、try節は変数だけでも良くなったので、上のサンプルを以下のように簡潔にできます。

try (fw) { // 変数の名前を記述するだけで良い
fw.write(“”あいうえお””);
} catch (IOException e) {
e.printStackTrace();
}

ジェネリクスの宣言が簡潔になった

Java 8では、ジェネリクスの宣言は以下のように、左辺と右辺の両方に型の記述が必要でしたが、

ArrayList<String> ary = new ArrayList<String>();
ary.add(“”あ””);

Java 11では、型推論により左辺だけでよくなりました。

ArrayList<String> ary = new ArrayList<>();
ary.add(“”あ””);

_を変数名に使用できなくなった

Javaは以下のように、_で桁区切りができます。
出力結果は、123456となります。
こちらの対応は人間が見て分かりやすくするためのものです。

int a = 123_456;

ただしそれを理由として、Java11では以下のように変数名に_を使えなくなっています。

int _ = 100;

ここまでJava 11の文法の仕様の追加・変更について記述してきましたが、次からは、Java 11の標準クラスの追加や変更点について解説します。

Stringクラスの改良

JavaのStringクラスは、内部的には文字をUTF-8の2バイトで保持します。

Java 11では、数字やアルファベットの半角のアスキー文字だけの文字列は、1バイトで保持します。メモリ使用量が軽減されます。

Java 11のStringには文字列を指定回数繰り返すrepeatメソッドが追加されています。

System.out.println(“”あいう””.repeat(3));

を実行すると、

あいうあいうあいう

となります。

Stringクラスの改良 その2

Java 11のStringには、空文字判定できるisBlankメソッドがあります。

String space = “”  “”; // 全角スペース+半角スペース
if (space.isBlank()) System.out.println(“”空文字です。””);

これを実行すると「空文字です」と表示されます。

改行毎の文字のStreamを取り出せるようになりました。

String str = “”あああ\r\nいいい\r\nううう””;
Object[] ary = str.lines().toArray();
for (Object o : ary) {
System.out.println(o);
}

上を実行すると以下のようになります。テキストを改行で区切りたい時に便利に使えます。

あああ
いいい
ううう

SE
Java 11ではたくさんの改良がされているのですね。
PM
Java 8からのJava 11への変更点を理解し、Java 11を使いこなしましょう。

Java 11は様々な改良が施されている

Java 8からのJava 11の主な変更点を紹介しましたが、ご理解頂けたでしょうか。ユーザの要望に応えて、細かい所が改善されていると感じたのではないでしょうか。

Javaはこれからも進歩を続けて行くことでしょう。


Javaでのキャリアアップをお考えの方は、現在募集中の求人情報をご覧ください。

また、直接のエントリーも受け付けております。

エントリー(応募フォーム)