Checked vs unchecked exceptions
Java is one of the few mainstream languages whose compiler enforces a rule about exceptions: every method that calls something that can throw a checked exception must either catch it or declare it on the method header with throws. Unchecked exceptions have no such requirement. The compiler enforces the rule mechanically (JLS §11.2: the handle-or-declare rule).
// Checked: compile error without `throws` or `try`:
public static void readFile(final String name) throws FileNotFoundException {
new Scanner(new File(name)); // FileNotFoundException is checked
}
// Unchecked: compiler is silent either way:
public static int divide(final int a, final int b) {
return a / b; // ArithmeticException is unchecked
}
The two categories map cleanly onto the class hierarchy:
- Checked: subclass of
Exceptionbut NOT ofRuntimeException. Examples:IOException,FileNotFoundException,SQLException,ParseException. - Unchecked: subclass of
RuntimeException(orError). Examples:NullPointerException,ArrayIndexOutOfBoundsException,IllegalArgumentException,ArithmeticException.
To classify a new exception: walk the parent chain. If RuntimeException appears, unchecked. Otherwise checked.
The design intent
Bloch Effective Java Item 70 articulates Java's intent:
- Use checked for recoverable conditions: situations where the caller might reasonably want to handle the failure and try something else (e.g., re-prompt for a filename, fall back to a default config, retry an HTTP request).
- Use unchecked for programming errors: situations where the caller violated a precondition the method documented (null where non-null required, index out of range, divide by zero).
The compiler enforcement reflects the intent. For checked exceptions, the caller is forced to acknowledge that recovery may be needed; the type system makes the failure path visible. For unchecked, the failure is the programmer's bug to fix in code, not a runtime branch to handle.
In practice, Java's checked-exception design is controversial: Bloch himself notes that checked exceptions can be over-used and that languages like C# and Kotlin (which have no checked-exception concept) work fine. CSCD 210 teaches the rule because the JDK enforces it; CSCD 211 revisits whether to throw checked or unchecked in new code.
The CS1 student-facing summary
For CSCD 210 purposes:
FileNotFoundExceptionis the canonical checked exception. Every method that opens a file mustthrowsit (or catch).NullPointerExceptionis the canonical unchecked exception. Nothrowsneeded; bug shows at runtime.Integer.parseIntthrowsNumberFormatException(unchecked) on bad input: nothrowsrequired, but careful programs catch it for user-facing input.
The five exceptions CSCD 210 students meet are catalogued in the roster that follows.
In other languages
- C#: no checked-exception concept. Every exception is what Java calls "unchecked." The XML documentation comments are the only signal of which exceptions a method may throw.
- Python: also no checked-exception concept. PEP 484 type hints can document exceptions, but the compiler does not enforce them.
- Kotlin: explicitly removed checked exceptions from the language even when interoperating with Java; calling a Java method that declares
throws IOExceptiondoes not force a Kotlin caller to handle it. - Swift: has a different mechanism:
throwsis part of the function type, and callers must usetrysyntax. Conceptually similar to Java's checked exceptions but more flexible.