Sealed Classes & Interfaces practice questions

From OCP Java SE 17 (1Z0-829) · 16 questions on this topic

Sealed Classes & Interfaces practice questions from OCP Java SE 17 (1Z0-829). This pack has 16 questions tagged Sealed Classes & Interfaces, drawn from its timed mock exams. 8 of them are worked through in full below — the question, every option, why each is right or wrong, and the explanation.

Worked examples for Sealed Classes & Interfaces

  1. Question 1

    What does this program print? ```java public class Main { static sealed class Shape permits Circle { String kind() { return "shape"; } } static final class Circle extends Shape { @Override String kind() { return "circle"; } } public static void main(String[] args) { Shape s = new Shape(); System.out.println(s.kind()); } } ```

    1. A. Compilation fails — Circle must be declared non-sealed, not final, in order to extend a sealed class

      Inverts the rule; a permitted subclass must be exactly one of final, sealed, or non-sealed, and final is a valid choice, so Circle being final is fine.

    2. B. Compilation fails — a sealed class must declare at least two permitted subclasses

      Invents a cardinality rule; one permitted subclass is allowed, the only requirement being at least one subtype somewhere.

    3. C. Compilation fails — a sealed class is implicitly abstract and cannot be instantiated

      Confuses sealed with abstract; sealed restricts who may extend but says nothing about instantiation, so a concrete sealed Shape can be instantiated.

    4. D. shapeCorrect answer

      sealed only restricts subclasses, not instantiation, so new Shape() is legal on this concrete class and s.kind() dispatches to Shape.kind(), printing shape.

    Explanation

    Trace: `sealed` restricts *who may extend* a class; it says nothing about whether the class itself may be instantiated. `Shape` is a concrete class with a body and an implicit no-arg constructor, so `new Shape()` is legal and `s.kind()` dispatches to `Shape.kind()`, printing `shape`. `Circle` is declared `final`, which satisfies the rule that every permitted subclass be `final`, `sealed`, or `non-sealed` — but nothing here ever creates a `Circle`. Why the others are wrong: `Compilation fails — a sealed class is implicitly abstract...` confuses two orthogonal modifiers. `abstract` controls instantiation; `sealed` controls the subclass set. A sealed class may be abstract, but it is not abstract by default — this one compiles and runs. `Compilation fails — Circle must be declared non-sealed, not final...` inverts the rule. A permitted subclass must be exactly one of `final`, `sealed`, or `non-sealed`. `final` (close the hierarchy here) is the most common choice; `non-sealed` (re-open it to anyone) is only one of the three. `Compilation fails — a sealed class must declare at least two permitted subclasses` invents a cardinality rule. One permitted subclass is fine; the only cardinality rule is that a sealed type must have *at least one* subtype somewhere, or javac reports `sealed class must have subclasses`. Exam tip: read `sealed` as "the permits list is the complete set of direct subtypes" — nothing more. Instantiability is still governed solely by `abstract`. The reverse trap: an `abstract sealed class` cannot be instantiated, and that is because of `abstract`, not `sealed`.

  2. Question 2

    What does this program print? ```java public class Main { sealed interface Shape permits Circle {} record Circle(double radius) implements Shape {} public static void main(String[] args) { int sealed = 4; var permits = 3; System.out.println(sealed * permits); } } ```

    1. A. Compilation fails — sealed is a reserved keyword and may not be used as a variable name

      Treats sealed like a reserved word; sealed is a contextual keyword, so it is an ordinary identifier in a local-variable declaration and int sealed = 4 compiles.

    2. B. Compilation fails — sealed and permits may not be used as identifiers in a file that declares a sealed type

      Imagines a file-scoped restriction; contextual keywords are resolved per grammatical position, so declaring a sealed type elsewhere has no effect on names inside main.

    3. C. Compilation fails — permits is a reserved keyword and may not be used as a variable name

      Treats permits like a reserved word; permits is contextual (recognised only in a type declaration), so var permits = 3 is a legal identifier.

    4. D. 12Correct answer

      sealed and permits are contextual keywords with special meaning only in type declarations, so as local variable names they are ordinary identifiers and 4 * 3 prints 12.

    Explanation

    Trace: `sealed`, `non-sealed` and `permits` were added as *contextual* keywords, not reserved words — adding reserved words would have broken existing code that already used those names. `sealed` and `permits` carry their special meaning only in the specific grammatical positions of a class or interface declaration. In a local-variable declaration they are ordinary identifiers, so `int sealed = 4;` and `var permits = 3;` both compile, and `4 * 3` prints `12`. Why the others are wrong: `Compilation fails — sealed is a reserved keyword...` treats `sealed` like `final` or `class`. It is not on the reserved-word list; existing code using `sealed` as a name still compiles under Java 17. `Compilation fails — permits is a reserved keyword...` makes the same mistake for `permits`, which is even more narrowly contextual — it is recognised only between a type's supertypes and its body. `Compilation fails — sealed and permits may not be used as identifiers in a file that declares a sealed type` imagines the restriction is file-scoped. Contextual keywords are resolved per grammatical position, not per compilation unit; the sealed `Shape` declaration above has no effect on the names available inside `main`. Exam tip: `sealed` and `permits` are contextual keywords, `non-sealed` is not — the hyphen makes it unusable as an identifier anyway, since `non-sealed` can never lex as a single name. Expect the exam to plant `sealed` as a variable or method name and dare you to call it a syntax error.

  3. Question 3

    Which keyword lets a permitted subclass of a sealed class re-open itself to unknown further subclasses?

    1. A. open

      Incorrect: open is a modifier for module declarations in module-info.java, not for classes.

    2. B. default

      Incorrect: default belongs to interface methods and switch labels, not class declarations.

    3. C. transient

      Incorrect: transient marks fields excluded from serialization; it says nothing about inheritance.

    4. D. non-sealedCorrect answer

      Correct: non-sealed removes the sealing constraint at that node — the class remains a permitted subclass of its sealed parent, but any class may now extend the non-sealed class itself.

    Explanation

    Re-opening a branch of a sealed hierarchy is done with the non-sealed modifier: it lifts the sealing constraint at that node so the type remains a permitted subclass of its sealed parent while allowing arbitrary further subclasses. non-sealed is Java's only hyphenated keyword and may appear only on a class or interface whose direct supertype is sealed. The other candidates are unrelated modifiers governing module declarations, interface methods and switch labels, or serialization — none of which affect inheritance.

  4. Question 4

    The sealed interface Shape declares no permits clause. What is the result of compiling and running this program? ```java public class Main { sealed interface Shape {} record Circle(double radius) implements Shape {} public static void main(String[] args) { final class Dot implements Shape {} Shape s = new Dot(); System.out.println(s instanceof Dot); } } ```

    1. A. Compilation fails — a sealed type with no permits clause has no permitted subtypes, so nothing may implement it

      Reads the missing permits clause as an empty one; when permits is omitted javac infers the permitted set from the same file, so the record Circle is a valid permitted subtype and the interface does have subtypes.

    2. B. Compilation fails — a local class may never be a permitted subtype of a sealed typeCorrect answer

      The spec prohibits a local (or anonymous) class from having a sealed direct supertype at all, so Dot is rejected with "local classes must not extend sealed classes".

    3. C. It prints true

      Assumes implicit inference sweeps up the local class Dot; inference considers only named types in the file, and a local class may not extend a sealed type anyway, so this does not compile.

    4. D. Compilation fails — implicit permits inference works only for sealed classes, not sealed interfaces, so Circle is rejected

      Invents an asymmetry; implicit permits inference applies to sealed interfaces exactly as to sealed classes, so the record Circle is accepted without being listed.

    Explanation

    Trace: when a sealed type omits `permits`, javac infers the permitted set from the types declared in the *same compilation unit* — so `Shape` really does have a permitted subtype here: the record `Circle`. That inference is deliberately restricted, though: it considers only classes and interfaces that have names in the class hierarchy of the file. A local class is not eligible, and the spec makes this an outright prohibition rather than a mere omission — a local (or anonymous) class may not have a sealed direct supertype at all. javac rejects `Dot` with `error: local classes must not extend sealed classes`, so the program never runs. Why the others are wrong: `It prints true` assumes implicit inference sweeps up everything in the file, including the local class. It does not — and even an explicit `permits Dot` would be impossible, because a local class has no name usable in a permits clause. `Compilation fails — a sealed type with no permits clause has no permitted subtypes...` misreads the missing clause as an empty one. If that were true, `Circle` would also be rejected; it is not. Note the different error you would get had the file contained *no* subtype at all: `sealed class must have subclasses`. `Compilation fails — implicit permits inference works only for sealed classes, not sealed interfaces...` invents an asymmetry. Inference applies to sealed interfaces exactly as it does to sealed classes, which is precisely why `Circle` compiles without being listed. Exam tip: the same prohibition covers anonymous classes — `new Shape() { }` fails with `anonymous classes must not extend sealed classes`. A sealed hierarchy must be enumerable by name at compile time, and local/anonymous classes have no such name. To re-open a hierarchy to unnamed subtypes you must route through a `non-sealed` subtype first.

  5. Question 5

    Which statement about sealed interfaces is correct?

    1. A. An interface that extends a sealed interface must be declared sealed or non-sealed — it can never be finalCorrect answer

      Correct: direct subtypes of a sealed type must each be final, sealed, or non-sealed, but no interface may be declared final, so a subinterface has only two choices: sealed or non-sealed.

    2. B. All permitted subtypes of a sealed interface must themselves be interfaces

      Incorrect: permitted subtypes of a sealed interface may be classes, interfaces, records, or enums.

    3. C. A sealed interface cannot list a record in its permits clause

      Incorrect: records are common permitted implementations, and their implicit finality satisfies the rule.

    4. D. A sealed interface must be declared in a named module

      Incorrect: sealed types work in the unnamed module too; the permitted subtypes must then share the sealed type's package.

    Explanation

    The modifier menu for a direct subtype of a sealed type is final, sealed, or non-sealed — but an interface can never be final, so a subinterface of a sealed interface must be either sealed or non-sealed. Permitted subtypes are not restricted to interfaces; classes, records, and enums are all allowed, records qualifying through implicit finality. Sealed types are also legal in the unnamed module, provided their permitted subtypes share the package.

  6. Question 6

    record Circle(double r) implements Shape is listed in the permits clause of the sealed interface Shape. Which modifier must Circle declare to compile?

    1. A. final, explicitly

      Incorrect: writing final on a record is legal but redundant; it is not required.

    2. B. non-sealed

      Incorrect: non-sealed would re-open the branch, which is meaningless for a record — a record is final and can never be extended.

    3. C. sealed, with an empty permits clause

      Incorrect: a sealed type must have at least one permitted subtype, and nothing can extend a record, so a sealed record cannot compile.

    4. D. None — a record class is implicitly final, which already satisfies the sealed-subtype ruleCorrect answer

      Correct: every direct subtype of a sealed interface must be final, sealed, or non-sealed — and a record class is implicitly final, so it satisfies the rule with no explicit modifier.

    Explanation

    Every direct subtype of a sealed interface must be final, sealed, or non-sealed. Because a record class is implicitly final, it already meets that requirement and needs no explicit modifier — records and sealed interfaces pair naturally for closed data hierarchies. Adding final would be redundant, while sealed or non-sealed are impossible or meaningless for a type that can never be extended.

  7. Question 7

    What is true of the permits clause for a sealed class?

    1. A. Permitted subclasses may live in any module without restriction

      Incorrect: permitted subclasses of a sealed class in a named module must be in that same module, and in the unnamed module they must be in the same package. Placement in any module without restriction is never allowed.

    2. B. A sealed class may have zero permitted subtypes and still be instantiated by clients freely

      Incorrect: a sealed class must have at least one permitted direct subtype, so sealing with nothing permitted is a compile-time error, and clients still could not subclass it freely.

    3. C. It may be omitted if all permitted subclasses are declared in the same source fileCorrect answer

      Correct: when a sealed class and all of its direct subclasses live in the same compilation unit (source file), the permits clause may be omitted and the compiler infers the permitted set from the declarations it finds there.

    4. D. permits can list interfaces the sealed class implements

      Incorrect: permits lists direct subclasses; interfaces the class implements belong in the implements clause, never in permits.

    Explanation

    The permits clause enumerates a sealed type's direct subtypes, but it is optional when the sealed class and all of those subtypes are declared in the same compilation unit — the compiler then infers the permitted set from what it finds in that file. Omission is tied to sharing the same source file, not merely the same package or module. The sealed class still must have at least one permitted subtype, those subtypes must be co-located with it, and the clause lists subclasses rather than implemented interfaces.

  8. Question 8

    A sealed interface permits one record and one ordinary class, and both are declared in the same file. What is the result? ```java public class Main { sealed interface Shape permits Circle, Square {} record Circle(double radius) implements Shape {} static class Square implements Shape { final double side; Square(double side) { this.side = side; } } public static void main(String[] args) { Shape s = new Circle(2.0); System.out.println(s instanceof Circle ? "circle" : "other"); } } ```

    1. A. Compilation failsCorrect answer

      Correct — every direct subtype of a sealed type must itself be declared final, sealed, or non-sealed; the plain class declares none, so it is rejected at compile time (JLS 17 §8.1.1.2).

    2. B. circle

      Assumes the whole file compiles because the record is fine; the record needs no modifier (records are implicitly final), but the sibling plain class lacks a required modifier and blocks compilation.

    3. C. other

      Also assumes successful compilation and then a false instanceof; the program never compiles because of the unmodified subclass.

    4. D. Throws IllegalAccessError

      Assumes sealing is checked at class-load time; the missing-modifier rule is enforced at compile time, so the program never reaches loading.

    Explanation

    Listing a type in a sealed type's permits clause is not sufficient — each direct subtype must itself close the hierarchy by declaring final, sealed, or non-sealed, or the seal could be reopened. Records satisfy this implicitly because they are final, but an ordinary permitted class that declares none of those modifiers is a compile-time error.

Practise all 16 Sealed Classes & Interfaces questions

OCP Java SE 17 has the full set, inside timed mock exams that mirror real exam conditions — every question with a worked explanation.

Open OCP Java SE 17

Other topics in this pack