In modern Java you could do this:
sealed interface Option<T> permits Some<T>, None<?> {}
record Some<T>(T value) implements Option<T> {}
record None() implements Option<T> {
static <T> None<T> none() { return new None<>(); // can also be a single instance
}
}
The only less than ideal part is that None needs the generic type, but that can be easily circumvented by adding a generic helper method. You can add all the Monad goodies to the Option interface and you will even get exhaustive switch cases with pattern matching. The only thing Java’s type system can’t express is abstracting those Monad goodies, but it can absolutely implement them on a case-by-case basis.