Add sealed module: modelling domains with sealed types and exhaustive switch

Payment model, permits and the three modifiers, default-branch trap, generic and recursive hierarchies, visitor comparison, run-time enforcement, modules. Transcripts from JDK 21, 25 and 27.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01TF9JWFvJSNm6HVzswzZU5a
This commit is contained in:
Claude
2026-09-24 12:03:59 +00:00
parent 65a4bbbbe3
commit ff6130bede
38 changed files with 638 additions and 0 deletions
+130
View File
@@ -0,0 +1,130 @@
$ javac broken/WalletNotHandled.java (21.0.10+7-Ubuntu-124.04)
broken/WalletNotHandled.java:10: error: the switch expression does not cover all possible input values
return switch (p) {
^
1 error
$ javac broken/WalletNotHandled.java (25.0.4.1+1-LTS)
broken/WalletNotHandled.java:10: error: the switch expression does not cover all possible input values
return switch (p) {
^
1 error
$ javac broken/WalletNotHandled.java (27+35)
broken/WalletNotHandled.java:10: error: the switch expression does not cover all possible input values
return switch (p) {
^
missing patterns:
Wallet _
1 error
$ javac broken/NotPermitted.java (21.0.10+7-Ubuntu-124.04)
broken/NotPermitted.java:5: error: class is not allowed to extend sealed class: Payment (as it is not listed in its 'permits' clause)
record Cheque(long amount) implements Payment {} // not in the permits clause
^
1 error
$ javac broken/NotPermitted.java (25.0.4.1+1-LTS)
broken/NotPermitted.java:5: error: class is not allowed to extend sealed class: Payment (as it is not listed in its 'permits' clause)
record Cheque(long amount) implements Payment {} // not in the permits clause
^
1 error
$ javac broken/NotPermitted.java (27+35)
broken/NotPermitted.java:5: error: class is not allowed to extend sealed class: Payment (as it is not listed in its 'permits' clause)
record Cheque(long amount) implements Payment {} // not in the permits clause
^
1 error
$ javac broken/MissingModifier.java (21.0.10+7-Ubuntu-124.04)
broken/MissingModifier.java:3: error: sealed, non-sealed or final modifiers expected
class Card implements Payment {} // must say final, sealed or non-sealed
^
1 error
$ javac broken/MissingModifier.java (25.0.4.1+1-LTS)
broken/MissingModifier.java:3: error: sealed, non-sealed or final modifiers expected
class Card implements Payment {} // must say final, sealed or non-sealed
^
1 error
$ javac broken/MissingModifier.java (27+35)
broken/MissingModifier.java:3: error: sealed, non-sealed or final modifiers expected
class Card implements Payment {} // must say final, sealed or non-sealed
^
1 error
$ javac broken/NoSubclass.java (21.0.10+7-Ubuntu-124.04)
broken/NoSubclass.java:2: error: sealed class must have subclasses
sealed interface Payment {} // no permits clause and no subtype in this file
^
1 error
$ javac broken/NoSubclass.java (25.0.4.1+1-LTS)
broken/NoSubclass.java:2: error: sealed class must have subclasses
sealed interface Payment {} // no permits clause and no subtype in this file
^
1 error
$ javac broken/NoSubclass.java (27+35)
broken/NoSubclass.java:2: error: sealed class must have subclasses
sealed interface Payment {} // no permits clause and no subtype in this file
^
1 error
$ javac broken/NonSealedWrongPlace.java (21.0.10+7-Ubuntu-124.04)
broken/NonSealedWrongPlace.java:3: error: non-sealed modifier not allowed here
non-sealed class Oops implements Plain {} // non-sealed only makes sense under a sealed supertype
^
(class NonSealedWrongPlace.Oops does not have any sealed supertypes)
1 error
$ javac broken/NonSealedWrongPlace.java (25.0.4.1+1-LTS)
broken/NonSealedWrongPlace.java:3: error: non-sealed modifier not allowed here
non-sealed class Oops implements Plain {} // non-sealed only makes sense under a sealed supertype
^
(class NonSealedWrongPlace.Oops does not have any sealed supertypes)
1 error
$ javac broken/NonSealedWrongPlace.java (27+35)
broken/NonSealedWrongPlace.java:3: error: non-sealed modifier not allowed here
non-sealed class Oops implements Plain {} // non-sealed only makes sense under a sealed supertype
^
(class NonSealedWrongPlace.Oops does not have any sealed supertypes)
1 error
$ javac broken/AnonymousSealed.java (21.0.10+7-Ubuntu-124.04)
broken/AnonymousSealed.java:5: error: anonymous classes must not extend sealed classes
return new Payment() {}; // an anonymous class is a subtype nobody listed
^
1 error
$ javac broken/AnonymousSealed.java (25.0.4.1+1-LTS)
broken/AnonymousSealed.java:5: error: anonymous classes must not extend sealed classes
return new Payment() {}; // an anonymous class is a subtype nobody listed
^
1 error
$ javac broken/AnonymousSealed.java (27+35)
broken/AnonymousSealed.java:5: error: anonymous classes must not extend sealed classes
return new Payment() {}; // an anonymous class is a subtype nobody listed
^
1 error
$ javac broken/xpkg/a/Base.java broken/xpkg/b/Impl.java (21.0.10+7-Ubuntu-124.04)
broken/xpkg/a/Base.java:2: error: class Base in unnamed module cannot extend a sealed class in a different package
public sealed interface Base permits b.Impl {}
^
1 error
$ javac broken/xpkg/a/Base.java broken/xpkg/b/Impl.java (25.0.4.1+1-LTS)
broken/xpkg/a/Base.java:2: error: class Base in unnamed module cannot extend a sealed class in a different package
public sealed interface Base permits b.Impl {}
^
1 error
$ javac broken/xpkg/a/Base.java broken/xpkg/b/Impl.java (27+35)
broken/xpkg/a/Base.java:2: error: class Base in unnamed module cannot extend a sealed class in a different package
public sealed interface Base permits b.Impl {}
^
1 error