By WebNest Studio Engineering Team
Java - Core Tutorial
Checked vs Unchecked Exceptions
Java splits exceptions into two enforcement categories at compile time: checked exceptions, which the compiler forces you to handle or declare, and unchecked exceptions, which you may handle but are never required to. This distinction is central to writing correct Java code and to understanding why some code compiles without a try-catch while other code refuses to compile without one.
Why it matters
Java is unusual in making the compiler enforce handling of some exceptions and not others. Knowing which is which explains why some calls demand a try-catch and others do not, and guides your own design: checked for conditions a caller can reasonably recover from, unchecked for bugs that should be fixed in the code.
Checked Exceptions
A checked exception is any class that extends Exception but does not extend RuntimeException. These represent conditions that are outside a program's control but are anticipated as part of normal, correct operation — a file that might not exist, a network connection that might drop, a database that might be unreachable. IOException and SQLException are classic examples. Because the compiler checks for these at compile time, any method that can throw one must either catch it or declare it with throws.
Unchecked Exceptions
An unchecked exception extends RuntimeException (which itself extends Exception). These typically represent programming mistakes rather than external conditions — dereferencing a null reference (NullPointerException), accessing an invalid array index (ArrayIndexOutOfBoundsException), or dividing an integer by zero (ArithmeticException). The compiler does not force you to catch or declare them, on the theory that a program riddled with such errors should usually be fixed, not defensively wrapped in try-catch everywhere.
Choosing and Recognizing Which Applies
A simple test: if you can imagine a caller genuinely recovering from the failure as part of normal operation (retry the network call, ask for a different file path), it fits the checked model. If the failure signals that something in the code itself is wrong (an off-by-one bug, a missing null check), it fits the unchecked model. Errors (like OutOfMemoryError) are a separate, third category and are neither checked nor meant to be routinely caught at all.
- Checked example:
IOException— must be caught or declared; represents an anticipated external failure. - Unchecked example:
NullPointerException— never required to be caught or declared; represents a programming defect. - Unchecked example:
ArrayIndexOutOfBoundsException— signals an index calculation bug rather than an external condition.
Example
A checked exception requiring handling versus an unchecked one that compiles without any
import java.io.IOException;
public class CheckedUncheckedDemo {
static void mustDeclare() throws IOException { // checked: compiler enforces this
throw new IOException("disk unavailable");
}
static void noDeclarationNeeded() {
String text = null;
System.out.println(text.length()); // unchecked: compiles fine, fails at runtime
}
public static void main(String[] args) {
try {
mustDeclare();
} catch (IOException e) {
System.out.println("Checked exception handled: " + e.getMessage());
}
try {
noDeclarationNeeded();
} catch (NullPointerException e) {
System.out.println("Unchecked exception handled: NullPointerException");
}
}
}
Checked exception handled: disk unavailable
Unchecked exception handled: NullPointerException
Common Mistakes
- Assuming "unchecked" means "cannot be caught" — unchecked exceptions can absolutely be caught, they are simply not required to be.
- Declaring "throws Exception" broadly on a method to silence the compiler instead of declaring the specific checked exception actually thrown.
- Wrapping every possible NullPointerException in try-catch instead of fixing the underlying null-handling bug that causes it.
- Forgetting that RuntimeException itself is a subclass of Exception, so "extends Exception" alone does not guarantee a checked exception.
Exercise
This program does not compile, because loadConfig declares a checked exception that main ignores. Handle it in main with a try-catch so the program prints the result for both calls.
Expected output: loaded then Config missing
import java.io.FileNotFoundException;
public class ConfigLoader {
static String loadConfig(boolean exists) throws FileNotFoundException {
if (!exists) {
throw new FileNotFoundException("Config missing");
}
return "loaded";
}
public static void main(String[] args) {
System.out.println(loadConfig(true));
System.out.println(loadConfig(false));
}
}
Show hints
- A checked exception must be caught or declared by every caller.
- Catch
FileNotFoundExceptionand printe.getMessage().
Show solution
import java.io.FileNotFoundException;
public class ConfigLoader {
static String loadConfig(boolean exists) throws FileNotFoundException {
if (!exists) {
throw new FileNotFoundException("Config missing");
}
return "loaded";
}
public static void main(String[] args) {
try {
System.out.println(loadConfig(true));
System.out.println(loadConfig(false));
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
}
}
}
Quick quiz
1. Which of these is a checked exception?
- A. NullPointerException
- B. ArithmeticException
- C. IOException
- D. ArrayIndexOutOfBoundsException
Show answer
C. IOException must be caught or declared. The other three extend RuntimeException and are unchecked.
2. Which of these is an unchecked exception?
- A. SQLException
- B. ClassNotFoundException
- C. IOException
- D. NullPointerException
Show answer
D. NullPointerException extends RuntimeException, so the compiler does not require it to be handled.
3. When is the handling of a checked exception verified?
- A. At compile time, by the compiler
- B. At runtime, by the JVM
- C. When the class is loaded
- D. It is never verified
Show answer
A. The compiler checks that every checked exception is either caught or declared, which is where the name comes from.
Interview questions
What is the difference between checked and unchecked exceptions?
Show answer
Checked exceptions are subclasses of Exception other than RuntimeException. The compiler forces every caller to catch them or declare them with throws. Unchecked exceptions are RuntimeException and its subclasses; they need no declaration or handling. Errors are also unchecked.
When should an exception be checked and when unchecked?
Show answer
Use a checked exception for a condition outside the program's control that a caller can reasonably recover from: a file that does not exist, a network that is down. Use an unchecked exception for a programming mistake that should be fixed rather than caught: a null argument, an index out of range, an object in an invalid state.
Key Points to Remember
- Checked exceptions extend Exception (not RuntimeException) and must be caught or declared — e.g. IOException, SQLException.
- Unchecked exceptions extend RuntimeException and are never required to be caught or declared — e.g. NullPointerException, ArithmeticException.
- Checked exceptions model anticipated external failures; unchecked exceptions typically model programming defects.
- Errors form a separate third category and are generally not meant to be caught at all.
Practice in the playground
Write and run your own code for this topic, or start from the exercise or an example. Runs plain Java 17. Frameworks such as Spring, and databases, are not available here. Your code for each topic is kept in this browser.
Run the examples
Change an input, predict the result, then compare it with the output. Explain why the result changes.
Written by
WebNest Studio Engineering Team
Practical lessons from developers working with Java, Python, React, databases and production systems.
Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering