There is an easy, but boilerplate heavy way to seal classes in Java. You put a private constructor in the base class then make subclasses inner classes of it.
public abstract class List<A> {
// private constructor is uncallable by any sublclasses except inner classes
private List() {
}
public static final class Nil<A> extends List<A> {
}
public static final class Cons<A> extends List<A> {
public final A head;
public final List<A> tail;
public Cons(A head, List<A> tail) {
this.head = head;
this.tail = tail;
}
}
}
Tack on a visitor pattern for dispatch.
My project [jADT: Java Algebraic DataTypes][1] generates all that boilerplate for you.
[1]: https://github.com/JamesIry/jADT