sealed(許可サブクラスの修飾子)難易度 高無料
次のコード(Java 17)のコンパイル結果として正しいものを選べ(全て同一ファイル・同一パッケージとする)。
1 sealed class Shape permits Circle, Square {}
2 final class Circle extends Shape {}
3 class Square extends Shape {}
- Aコンパイルエラー(
Squareがfinal/sealed/non-sealedのいずれでもない) - Bコンパイル成功。
permitsに列挙されていればサブクラス側の修飾子は不要。 - Cコンパイルエラー(許可サブクラスはすべて
finalでなければならない) - Dコンパイルエラー(
permitsは別ファイルの型を指定できない)
正解・解説・誤答理由・ひっかけを見る▼ open
✓ 正解:AAI作成・独立検証済
解説
sealed クラス/インタフェースの直接のサブクラス(permits で許可された型)は、必ず次の3修飾子のいずれかで宣言しなければならない(JLS §8.1.1.2)。
final… それ以上継承させない(=封印を閉じる)sealed… さらにpermitsで継承を限定する(封印を続ける)non-sealed… 明示的に封印を解除し誰でも継承可にする
2行目 Circle は final なので適格。しかし3行目 Square はどの修飾子も付いていないため、
「封印を閉じるのか・続けるのか・解くのか」が不定になりコンパイルエラーになる。
Square を final/sealed/non-sealed のいずれかにすれば通る。
- B
permitsは「誰が継承してよいか」を決めるだけ。許可された各サブクラスはfinal/sealed/non-sealedのいずれかを必ず宣言する義務がある。 - C
finalは3つの選択肢の1つに過ぎない。sealedやnon-sealedでも適格なので「全て final」は誤り。 - D本問は全て同一ファイル。エラーの原因は
Squareの修飾子欠落であってpermitsの記述場所ではない。
ひっかけ:
record は暗黙に final なので sealed の許可対象にそのまま置けるが、通常の class は自動で final にならない。「permits に書けば継承の可否は解決済み」と誤解し、サブクラス側の修飾子を付け忘れるのが典型。実機確認の答え合わせ
javac でコンパイル:
Shape.java:3: error: sealed, non-sealed, or final modifiers expected
class Square extends Shape {}
^
→ コンパイル不成立(実行に至らない)。AIが作成し、独立した検証を経た解説です(有資格者による監修は経ていません)