Checked exceptions (subclasses of Exception, not RuntimeException) must be declared or handled and are meant for recoverable conditions; unchecked (RuntimeException) signal programming errors or unrecoverable states and need no declaration.
Many modern frameworks (Spring) favor unchecked exceptions because checked exceptions force boilerplate, leak across abstraction layers, and don't compose with lambdas/streams (functional interfaces don't declare them). The trade-off is checked exceptions document recoverable failures at compile time, which is genuinely valuable for true business-recoverable cases like IO.
- Catching Exception everywhere and ignoring it.
- Wrapping every checked exception in RuntimeException without context.