What exceptions are
An exception is an object Java uses to report that something went wrong: division by zero, an index past the end of an array, a missing file. When an exception occurs, the normal flow of the program stops. If nobody handles it, the program ends and prints a description of the error.
The first exception
Let's divide an integer by zero:
void main() {
int apples = 10;
int people = 0;
IO.println("Starting to divide");
IO.println(apples / people);
IO.println("This line will not run");
}Output:
Starting to divide
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.main(Main.java:6)The first line got printed, and after the error the program stopped. We say the code threw an exception.
How to read the message
An exception message has three parts:
java.lang.ArithmeticException— the type of the exception, that is, its class. It tells you right away what kind of error it is./ by zero— the message with details.at Main.main(Main.java:6)— the stack trace: exactly where the error happened. Here it's in themainmethod, line 6.
If the error happened deep inside nested calls, there are several at lines. The top one is where the exception occurred; the ones below show who called that code.
int divide(int a, int b) {
return a / b;
}
void main() {
IO.println(divide(10, 0));
}Output:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.divide(Main.java:2)
at Main.main(Main.java:6)Common exceptions
Beginners run into these exceptions most often:
| Exception | When it happens |
|---|---|
ArithmeticException | integer division by zero |
ArrayIndexOutOfBoundsException | an index outside the array |
NullPointerException | calling a method on null |
NumberFormatException | a string could not be turned into a number |
IllegalArgumentException | a method got an invalid argument |
For example, Integer.parseInt doesn't understand letters:
void main() {
int age = Integer.parseInt("twenty");
}Output:
Exception in thread "main" java.lang.NumberFormatException: For input string: "twenty"
at Main.main(Main.java:2)The exception hierarchy
All exceptions are objects of classes that inherit from Throwable. It has two branches:
Error— serious failures of the virtual machine itself, such as running out of memory (OutOfMemoryError). They are usually not handled. Where such failures come from is covered in the Memory and garbage collection lesson.Exception— errors a program can deal with. Its subclassRuntimeExceptiongroups mistakes in the code's logic: division by zero,null, a wrong index.
How this split affects your code is covered in the lesson on checked and unchecked exceptions.
An exception is an object too
Since an exception is an object, it has methods. getMessage() returns the message and getClass().getSimpleName() the short class name. To get hold of the exception object, you catch it with try-catch — the topic of the next lesson:
void main() {
try {
int[] scores = {5, 4, 3};
IO.println(scores[3]);
} catch (ArrayIndexOutOfBoundsException e) {
IO.println(e.getClass().getSimpleName());
IO.println(e.getMessage());
}
}Output:
ArrayIndexOutOfBoundsException
Index 3 out of bounds for length 3Common mistake
The most common exception in Java is NullPointerException: a method is called on null, that is, on "nothing". For example, a method returned null and the result was used right away:
String findName() {
return null;
}
void main() {
IO.println(findName().length());
}Output:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because the return value of "Main.findName()" is null
at Main.main(Main.java:6)Modern Java explains in detail what exactly turned out to be null: here, the result of findName(). Before calling methods on a value that may be missing, check it (if (name != null)) or return an Optional from the method.