0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

# Java 17の新機能まとめ — sealedクラス・テキストブロック・パターンマッチングを整理

0
Posted at

Java 17の新機能まとめ — sealedクラス・テキストブロック・パターンマッチングを整理

はじめに

Java 17はLTS(長期サポート)バージョンで、現在の実務プロジェクトでも広く採用されています。

この記事では、Java 17で使えるようになった主要な新機能を3つ取り上げて、実務での使いどころを整理します。

機能 正式採用バージョン
テキストブロック Java 15
パターンマッチング(instanceof) Java 16
sealedクラス Java 17

1. テキストブロック — 複数行文字列をすっきり書く

複数行の文字列をこれまでどう書いていましたか?

// 旧来の書き方:エスケープと連結だらけ
String json = "{\n" +
              "  \"name\": \"田中太郎\",\n" +
              "  \"age\": 25\n" +
              "}";

テキストブロックを使うと:

// テキストブロック:読みやすい
String json = """
        {
          "name": "田中太郎",
          "age": 25
        }
        """;

""" で囲むだけです。\n\" のエスケープが不要になります。

実務での使いどころ

// SQLクエリ
String sql = """
        SELECT u.id, u.name, u.email
        FROM users u
        WHERE u.active = true
          AND u.age >= 20
        ORDER BY u.name
        """;

// HTMLテンプレート
String html = """
        <html>
          <body>
            <h1>%s</h1>
            <p>%s</p>
          </body>
        </html>
        """.formatted(title, body);

注意: インデントは """ の終端位置に合わせて自動で除去されます。


2. パターンマッチング(instanceof) — キャストを1行に

これまでの instanceof チェックはこう書いていました:

// 旧来の書き方:instanceof → キャスト → 使用 の3ステップ
Object obj = "Hello, Java";

if (obj instanceof String) {
    String s = (String) obj;  // キャストが必要
    System.out.println(s.toUpperCase());
}

パターンマッチングを使うと:

// パターンマッチング:instanceof + キャストを1行に
Object obj = "Hello, Java";

if (obj instanceof String s) {  // sに直接束縛される
    System.out.println(s.toUpperCase());
}

さらに条件も一緒に書けます:

// 型チェック + 条件を同時に
if (obj instanceof String s && s.length() > 5) {
    System.out.println("長い文字列: " + s);
}

実務での使いどころ

// 複数の型を処理する場合
public String describe(Object obj) {
    if (obj instanceof Integer i) {
        return "整数: " + i;
    } else if (obj instanceof String s) {
        return "文字列: " + s;
    } else if (obj instanceof List<?> list) {
        return "リスト(" + list.size() + "件)";
    }
    return "その他: " + obj;
}

3. sealedクラス — 継承できるクラスを制限する

sealed を使うと、どのクラスがこのクラスを継承できるかを明示的に宣言できます。

// sealedクラスの宣言:permitsで継承を許可するクラスを列挙
public sealed class Shape permits Circle, Rectangle, Triangle {
    public abstract double area();
}

// 許可されたサブクラス
public final class Circle extends Shape {
    private final double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
}

public final class Rectangle extends Shape {
    private final double width;
    private final double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    @Override
    public double area() {
        return width * height;
    }
}

permits に書かれていないクラスは Shape を継承できません:

// コンパイルエラー:Squareはpermitsに含まれていない
public class Square extends Shape { ... }  // ❌

sealedと一緒に使うサブクラスの修飾子

修飾子 意味
final これ以上継承不可
sealed さらに継承を制限する(孫クラスも制御)
non-sealed 制限を解除(誰でも継承可能)

実務での使いどころ

ドメインモデルで「取りうる状態を明示したい」場面に有効です:

// 注文ステータスの表現
public sealed class OrderStatus permits Pending, Approved, Shipped, Cancelled {
    public abstract String label();
}

public final class Pending extends OrderStatus {
    @Override public String label() { return "受付中"; }
}

public final class Approved extends OrderStatus {
    @Override public String label() { return "承認済み"; }
}

permits に宣言した型だけが存在できるため、コンパイラが「漏れ」を検知してくれます。


まとめ

機能 解決する問題 一言
テキストブロック 複数行文字列のエスケープ地獄 """ で囲むだけ
パターンマッチング instanceof → キャストの冗長さ 型チェックと変数束縛を1行に
sealedクラス 継承の範囲が不明確 permits で継承先を宣言

Java 17はLTSなので、現場でも積極的に使われています。特にテキストブロックパターンマッチングは導入コストが低く、すぐに使えます。コードが一気にすっきりするので、ぜひ試してみてください。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?