S-JIS[2020-11-08/2023-09-23] 変更履歴

シールクラス(Java15〜16)

Java15〜16のシールクラス(プレビュー版)について。


概要

2020/9/15にリリースされたJava15で、プレビュー版としてsealed class(シールクラス)が使えるようになった。

クラス定義でsealedを付けると、「そのクラスを継承できるクラス」を限定することが出来る。
permitsで継承可能なクラスを指定する。

public abstract sealed class Shape permits Circle, Rectangle, Square {
}

public final class Circle extends Shape {
}

public sealed class Rectangle extends Shape permits TransparentRectangle, FilledRectangle {
}

public non-sealed class Square extends Shape {
}

Java15時点ではこれ以上の意味は無いが、
将来的にはシールクラスをswitch文/式で使って、caseで全ての子クラスが指定されているかどうかをチェックしたりする予定らしい。

Java16では「permits」「sealed」「non-sealed」はcontextual keywordsになった模様。[2021-03-21]
つまり、permits・sealedといった変数名は従来通り使用できる。
(non-sealedはハイフン入りのキーワードなので、変数名としてはそもそも使用できない)

Java17でシールクラスは正式版になったが、switch文/式での使用はプレビュー機能のままであり、Java21で正式版になった。[2023-09-23]


sealed classを直接カタカナに直すと、「シールドクラス」になる。
が、シールドだとshield(盾)をイメージしてしまうので、シールドにはしない方がいいと思う。

個人的には「封印クラス」という訳語を推したいところだが、
Java15のjavacのコンパイルエラーメッセージでは「シール・クラス」になっている。
sealは、あのペタッと貼るシールと同じ言葉らしい。


シールクラスはJava15〜16ではプレビュー版の機能なので、この機能を使いたい場合はコンパイル時にjavacコマンドに--enable-previewを付ける必要があり、
また、実行時にjavaコマンドに--enable-previewを付ける必要がある。
JShellで試す場合もjshellコマンドに--enable-previewを付ける。

> javac --enable-preview --release 15 Example.java
> java --enable-preview Example

シールクラスの例

シールクラスの例 備考
public sealed class A permits A1, A2, A3 {
}
シールクラスは、classの前にsealedを付ける。
permitsで、継承を許すクラスを指定する。
public final class A1 extends A {
}
継承する側の子クラスは、final(またはsealedまたはnon-sealed)にする必要がある。
finalになっていないと、「sealed、non-sealedまたはfinal修飾子が必要です」というコンパイルエラーになる。
public sealed class A2 extends A permits A21 {
}

public final class A21 extends A2 {
}
継承する子クラスをsealedにすると、そのクラスからさらに子クラスを限定して作ることが出来る。
public non-sealed class A3 extends A {
}

public class A31 extends A3 {
}
non-sealedを指定する例。
public final class A4 extends A {
}
親クラスでpermits宣言されていないクラスを定義しようとすると、
「クラスはシール・クラスAを拡張できません」というコンパイルエラーになる。

プレビュー機能へ戻る / Java目次へ戻る / 新機能へ戻る / 技術メモへ戻る
メールの送信先:ひしだま