java-21 について
Java 21 のアプリケーションやライブラリ開発向けのコーディングスキルです。不変データ、シールド型階層、仮想スレッドのパターンを扱います。
主な機能
- 01record による不変データの表現
- 02コンパクトコンストラクターでのデータ検証
- 03シールド型とパターンマッチングによる階層設計
- 04ブロッキング I/O での仮想スレッド利用
- 05可変 DTO とリクエストごとのプラットフォームスレッドの回避
活用シーン
- 01不変 DTO や値オブジェクトの設計
- 02閉じた型階層のモデル化
- 03ブロッキング I/O タスクの拡張
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ gentleman-programming/ gentleman-skills --skill java-21インストール後、Claude Code で/java-21を入力して読み込まれたか確認します。
詳細
使用する場面
以下の場合にこのスキルを読み込みます:
- Java 21 アプリケーションまたはライブラリのコードを記述するとき
- イミュータブルな DTO や値オブジェクトを設計するとき
- sealed 型で閉じた階層をモデル化するとき
- ブロッキング I/O に仮想スレッドを使用するとき
重要なパターン
パターン 1:イミュータブルなデータにはレコードを使用する
DTO と値オブジェクトにはレコードを使用し、コンパクトコンストラクターで検証します。
パターン 2:sealed 型とパターンマッチング
sealed インターフェース/クラスと switch のパターンマッチングを使用して、網羅性を確保します。
パターン 3:I/O には仮想スレッドを使用する
大規模なスレッドプールを使わずにブロッキング I/O を処理するには、仮想スレッドを使用します。
コード例
例 1:検証付きレコード
package com.acme.user;
public record Email(String value) {
public Email {
if (value == null || !value.contains("@")) {
throw new IllegalArgumentException("Invalid email");
}
}
}
例 2:sealed 階層と switch のパターンマッチング
package com.acme.payment;
public sealed interface Payment permits Card, BankTransfer { }
public record Card(String last4) implements Payment { }
public record BankTransfer(String iban) implements Payment { }
public final class PaymentPrinter {
public String describe(Payment payment) {
return switch (payment) {
case Card card -> "card-" + card.last4();
case BankTransfer bank -> "iban-" + bank.iban();
};
}
}
例 3:ブロッキング呼び出しに仮想スレッドを使用する
package com.acme.io;
import java.util.concurrent.Executors;
public final class Fetcher {
public void fetchAll(java.util.List<String> urls) throws Exception {
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
for (String url : urls) {
executor.submit(() -> blockingFetch(url));
}
}
}
private void blockingFetch(String url) {
// perform blocking I/O here
}
}
アンチパターン
避ける:ミュータブルなデータキャリアを使用する
// BAD: mutable DTO
public class UserDto {
public String name;
public String email;
}
避ける:リクエストごとにプラットフォームスレッドを直接起動する
// BAD: expensive and unbounded
new Thread(() -> blockingFetch("https://api" )).start();
クイックリファレンス
| タスク | パターン |
|---|---|
| イミュータブルな DTO | 検証付きのレコードを使用する |
| 閉じた階層 | sealed インターフェースと switch を使用する |
| ブロッキング I/O のスケール | 仮想スレッドのエグゼキューターを使用する |
リソース
- Java 21 リリースノート:https://www.oracle.com/java/technologies/javase/21-relnote-issues.html
- JEP インデックス:https://openjdk.org/jeps/0
コメント
Markdown 対応