Search code examples
javasealed-classjava-15java-sealed-type

What is the difference between a final and a non-sealed class in Java 15's sealed-classes feature?


I have the following sealed interface (Java 15):

public sealed interface Animal permits Cat, Duck {

    String makeSound();
}

This interface is implemented by 2 classes:

public final class Cat implements Animal {

    @Override
    public String makeSound() {
        return "miau";
    }
}

public non-sealed class Duck implements Animal {

    @Override
    public String makeSound() {
        return "quack";
    }
}

Can someone tell me the difference between final and non-sealed? final stops me from creating other sub-classes but what behavior does non-sealed apply to Duck?


Solution

    • As you've marked Cat as final, no other class can extend Cat.
    • As you've marked Duck as non-sealed, any class can extend Duck.

    When marking a class as sealed, all directly extending classes (the ones after the permits clause) have to be marked either as final, sealed or non-sealed:

    • Marking a class that extends a sealed class as sealed, applies the same effect on it: Only classes specified after the permits clause are allowed to extend it.

    • non-sealed just "breaks the seal", so the effect doesn't have to be carried on down the hierarchy. The extending class is open (again) for being extended by unknown subclasses itself.

    • final is effectively the same as sealed without any class specified after the permits clause. Notice that specifying nothing after permits is not possible, so sealed cannot replace final.