Remix.run Logo
lock1 2 days ago

The only way to handle a checked exception is either by declaring `throws` in the function signature to propagate it, or by using annoying try-catch statement. Then, due to the verbosity of try-catch, some decided to misuse it with an empty catch block.

Personally, I think the problem isn't the checked exception itself, but rather the exception handling mechanism & popularity of unchecked exceptions. This led to some people misusing empty catch blocks or rethrowing with unchecked exception. Java 8+ functional interfaces / lambdas also don't play nicely with checked exceptions. There's no new keyword/feature/interaction between lambdas & checked exception, only old try-catch.

To this day (Java 24 and soon LTS 25), AFAIK there's 0 plan to improve Java checked exception. And there are a lot of quirks if you try to use checked exception with modern Java features. It's just all around painful to work with, and I prefer to use Result<T,E>-like with `sealed` sum-type nowadays.

It's quite weird the direction Java, C#, Javascript communities take on this. Lots of people just go with unchecked or using nullable reference. Which is fine for a throwaway program, but quite painful in a larger project. What do you mean a subtype / child class doesn't provide a supposedly "must be implemented" method `abstractMethod()` and instead throws an unchecked exception when you call it?

You can even see this in JDK standard library, take java.util.Collection.removeAll() for example (https://docs.oracle.com/javase/8/docs/api/java/util/Collecti...). A class implementing `Collection` interface might or might not throw unchecked exception, yet you can still do this and get runtime error:

  Collection<T> c = new ImmutableList<T>();
  c.removeAll();
Meanwhile, modern PLs with a better type system (e.g. Haskell, Rust, Zig) don't shy away from using Result<>-like and provides special syntax like Rust's Try trait operator (?) or Haskell's bind (>>=). This is pretty much similar to Java's checked exception in a lot of ways (explicit function signature declaration, type system enforcement, short-circuiting property, non-local goto). It's kind of sad that Java completely neglected checked exceptions, leaving them like an abandoned child rather than improving them like other modern PLs.