1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

こんにちは、私です。

前回のJava8→9編では、jshellList.of() など、Java9の新機能を一緒にレベルアップしました。

今回はその続き。Java9→10編です。

Java10は短命リリース(LTSではない)なので、「えっこんだけ?」と思うかもしれません。でも、その分だけ1つの機能がぶっ刺さる回になっています。

お察しの方もいると思いますが——そう、var の話です。

「変数名の前に型を書かなくていい? それって……ローカル変数型推論能力(ヴァリアブル・インフェランス)ってことか?」

まあ、そんな感じです。やっていきましょう。

対象読者

  • Java8→9編を読んだ方(または、Java9の概要を知っている方)
  • var を聞いたことはあるが、どこで使えてどこで使えないか曖昧な方

環境

項目 バージョン
Java 10(確認: java -version
前回 Java 9

Java9からJava10へのレベルアップ

1. ローカル変数型推論 — var

Java10の目玉、そしてこの記事のほぼすべてです。
これだけでも十分だったかも?

var とは何か

ローカル変数の型宣言を、コンパイラに推論させる構文です。

// Java9以前
String message = "こんにちは";
List<String> names = new ArrayList<>();

// Java10以降
var message = "こんにちは";   // String と推論される
var names = new ArrayList<String>();  // ArrayList<String> と推論される

コンパイル時に型が確定するので、動的型付けではありません。コンパイラが「右辺を見れば型は分かるだろ」と言っているだけです。

どこで使えるか(超重要)

var はどこでも使えるわけではありません。ローカル変数(メソッド内の変数)に限定されます。

// ✅ 使える — ローカル変数
void example() {
    var count = 10;
    var list = List.of("a", "b");
    for (var item : list) {
        System.out.println(item);
    }
}

// ❌ 使えない — フィールド(クラス変数)
class MyClass {
    var name = "田中";  // コンパイルエラー
}

// ❌ 使えない — メソッドの引数
void doSomething(var input) {  // コンパイルエラー
}

// ❌ 使えない — 戻り値の型
var getName() {  // コンパイルエラー
}

初期化が必須

var は右辺から型を推論するため、宣言と同時に初期化しなければなりません。

// ❌ コンパイルエラー
var x;
x = 10;

// ✅ OK
var x = 10;

null だけでは使えない

// ❌ コンパイルエラー(型が推論できない)
var obj = null;

// ✅ キャストすれば OK
var obj = (String) null;

実務でどう使うか

長い型名を短く書けるのが一番の恩恵です。特にジェネリクスが絡むと効果抜群です。

// Java9以前(型名が長い…)
Map<String, List<Integer>> scoreMap = new HashMap<String, List<Integer>>();

// Java10以降(右辺で型は分かるので左辺はvarに)
var scoreMap = new HashMap<String, List<Integer>>();

ただし、可読性が落ちる使い方はやめましょう

// 😕 右辺を見ても型が分かりにくい❌
var result = process();  // process() が何を返すか一目で分からない

// 👍 型が明白な場合に使う
var user = new User("田中", 30);  // User であることは明らか

var はあくまで「型が自明なときの省略」です。「型を隠す」のが目的ではありません。

2. コレクションのコピー — List.copyOf() / Map.copyOf() / Set.copyOf()

Java9で List.of() / Map.of() / Set.of() が追加されましたが、Java10では 既存のコレクションから不変コピーを作る copyOf() が追加されました。

// 変更可能なリストを作る
var mutableList = new ArrayList<>(List.of("A", "B", "C"));
mutableList.add("D");

// 不変コピーを作る
var immutableCopy = List.copyOf(mutableList);
// immutableCopy.add("E");  // → UnsupportedOperationException

System.out.println(immutableCopy); // [A, B, C, D]

List.of() との違い

  List.of(...) List.copyOf(collection)
入力 個々の要素 既存コレクション
nullの扱い null要素を含むと例外 null要素を含むと例外
用途 新規作成 既存リストのスナップショット

実務では「このメソッドの外にリストを渡したいが、元のリストは変えられたくない」というときに copyOf() が効きます。

3. Optional の orElseThrow()(引数なし版)

Java8で登場した Optional に、Java10で 引数なしの orElseThrow() が追加されました。

// Java8〜9の書き方(やや冗長に書くしかなかった)
var name = Optional.ofNullable(user.getName())
    .orElseThrow(() -> new NoSuchElementException());

// Java10以降(引数なしで同じ意味)
var name = Optional.ofNullable(user.getName())
    .orElseThrow();  // 値がなければ NoSuchElementException をスロー

地味な変更ですが、「あれ、引数なしで書けなかったっけ?」と迷う時間がゼロになります。

その他の変更(軽め)

  • アプリケーションクラスデータ共有(AppCDS)の改善: JVMの起動時間短縮に関わる機能。実感できるのは大規模アプリ。
  • 並列 GC のインターフェース整備: GC(ガベージコレクタ)の内部リファクタリング。アプリ開発者が直接意識することは少ない。
  • スレッドローカルハンドシェイク: JVM内部の改善。アプリコードからは基本的に不透明。

実務でJava10に上げるときの注意

Java10はLTSではないため、「10で止まる」という選択肢は基本的にありません。10に上げる場合、次のLTSである11への通過点として扱うのが現実的です。

私自身の実務(WebEntryのJava 8→21アップグレード)では、8から21へ直接移行していました。10や11で「変わったこと」の一覧を知らないまま乗り越えていたわけです。この連載はその棚卸しでもあります。「飛び級でアップグレードした人間の振り返り」だと思って読んでいただけると、味わいが増すかもしれません。

おわりに

Java10の目玉は var です。以上です(清々しいくらいシンプルな回)。

ただ、var は使い方を間違えると可読性を下げる諸刃の剣でもあります。「型が自明なとき」「右辺を見れば分かるとき」だけ使うのが吉です。

次回は Java10→11編 です。Java11はLTSなので機能が増えます。標準 HttpClient、文字列の新メソッド群、単一ファイル実行など、実務で効く変化が揃っています。一緒にレベルアップを目指しましょう。

→ [Java10→11編](公開後にリンクを追加します)


参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?