Record と Sealed 型
閉じた階層構造をモデル化します。
「Record と Sealed 型」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。
sealedとレコードの組み合わせ
sealedインターフェースとレコードは、相性のよい組み合わせです。sealedインターフェースでケースの閉じた集合を定義し、各レコードで具体的かつ不変なケースを表します。これらを組み合わせることで、代数的データ型をモデル化できます。
レコードは暗黙的にfinal
レコードは自動的にfinalになるため、許可されるサブタイプがfinal、sealed、non-sealedのいずれかでなければならないという規則を満たします。追加の修飾子は必要ありません。
閉じた形状の継承階層
形状をsealedインターフェースを実装するレコードとしてモデル化し、それぞれに固有のデータを持たせます。
public class Main {
sealed interface Shape permits Circle, Rectangle {}
record Circle(double radius) implements Shape {}
record Rectangle(double width, double height) implements Shape {}
public static void main(String[] args) {
Shape s = new Rectangle(3, 4);
System.out.println(s);
}
}振る舞いの追加
sealedインターフェースで、すべてのレコードが実装するメソッドを宣言できます。これにより、閉じた集合に対してポリモーフィズムを利用できます。
public class Main {
sealed interface Shape permits Circle, Rectangle {
double area();
}
record Circle(double radius) implements Shape {
public double area() { return Math.PI * radius * radius; }
}
record Rectangle(double width, double height) implements Shape {
public double area() { return width * height; }
}
public static void main(String[] args) {
Shape s = new Circle(2);
System.out.printf("Area: %.2f%n", s.area());
}
}equalsとtoStringの自動生成
レコードはequals、hashCode、toStringを自動的に生成します。同じコンポーネントを持つ2つのレコードは等しいため、値のモデル化に適しています。
public class Main {
sealed interface Shape permits Circle {}
record Circle(double radius) implements Shape {}
public static void main(String[] args) {
Circle a = new Circle(5);
Circle b = new Circle(5);
System.out.println(a.equals(b));
System.out.println(a);
}
}結果のモデル化
よくあるパターンとして、成功レコードと失敗レコードを持つsealedな結果型があります。これは、予想される結果を表す場合に、nullを返したり例外を使ったりする方法の代わりになります。
public class Main {
sealed interface Result permits Ok, Err {}
record Ok(int value) implements Result {}
record Err(String message) implements Result {}
static Result parse(String s) {
try { return new Ok(Integer.parseInt(s)); }
catch (NumberFormatException e) { return new Err("bad number: " + s); }
}
public static void main(String[] args) {
System.out.println(parse("42"));
System.out.println(parse("oops"));
}
}検証のためのコンパクトコンストラクター
レコードでは、コンパクトコンストラクターで入力値を検証できます。これにより、それぞれのケースを生成時点で正しい状態に保てます。
public class Main {
sealed interface Shape permits Circle {}
record Circle(double radius) implements Shape {
Circle {
if (radius < 0) throw new IllegalArgumentException("radius must be >= 0");
}
}
public static void main(String[] args) {
try { new Circle(-1); }
catch (IllegalArgumentException e) { System.out.println(e.getMessage()); }
}
}再帰的なデータモデル
レコードはsealedインターフェースを参照できるため、式ツリーや連結リストのような再帰的な構造を構築できます。
public class Main {
sealed interface Expr permits Num, Add {}
record Num(int value) implements Expr {}
record Add(Expr left, Expr right) implements Expr {}
public static void main(String[] args) {
Expr e = new Add(new Num(1), new Add(new Num(2), new Num(3)));
System.out.println(e);
}
}不変性の利点
レコードは浅い意味で不変なので、レコードによるsealedな継承階層は理解しやすく、安全に共有でき、並行処理にも適しています。レコード自体を防御的にコピーする必要はありません。
switchとの組み合わせ
sealedレコードは、パターンマッチングを使うswitchと組み合わせると特に効果を発揮します。各ケースでレコードを分解でき、コンパイラーがすべてのケースを網羅しているか確認します。この内容はパターンのコースで詳しく扱います。
モデルに対する計算
再帰的なレコードのツリーをたどるメソッドとして、インタープリターを記述できます。
public class Main {
sealed interface Expr permits Num, Add {}
record Num(int value) implements Expr {}
record Add(Expr left, Expr right) implements Expr {}
static int eval(Expr e) {
if (e instanceof Num n) return n.value();
Add a = (Add) e;
return eval(a.left()) + eval(a.right());
}
public static void main(String[] args) {
Expr e = new Add(new Num(4), new Add(new Num(5), new Num(6)));
System.out.println(eval(e));
}
}理解度チェック
sealedレコードについての理解度を確認しましょう。
まとめ
sealed型とレコードを組み合わせる方法を学びました。
- レコードは暗黙的にfinalなので、許可されるサブタイプとしてそのまま組み込めます。
- sealedインターフェースで共有メソッドを宣言できます。
- レコードによって、等価性、ハッシュ、toStringが自動的に提供されます。
- これらを組み合わせると、閉じた不変の、場合によっては再帰的なデータをモデル化できます。
よくある質問
「Record と Sealed 型」レッスンは無料ですか?
はい。「Record と Sealed 型」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。
「Record と Sealed 型」で何を学びますか?
閉じた階層構造をモデル化します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Java Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「Record と Sealed 型」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJava Academyレッスンでコードを書いて実行できますか?
はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Sealed 型の宣言
- permits 節
- Record と Sealed 型
- Sealed 型に対する網羅的な switch