Java Exception Handling
Exception Handling
An exception is an abnormal situation that occurs while a program is running.
In programming, there are two kinds of errors: errors that occur at compile time and errors that occur at runtime. Compile-time errors happen because of syntax errors or code that does not fit the context, so the program itself cannot even run. Runtime errors, by contrast, occur in unexpected situations while the program is running, causing malfunction or program termination.
For example, many exceptional situations can occur: referencing an object after only declaring it and before creating it, dividing an integer by 0, trying to access a file that does not actually exist, or accessing an index outside the bounds of an array.
Java calls these runtime errors exceptions and lets you handle exceptional situations.
Exception-Related Classes
- java.lang.Object
- java.lang.Throwable
- java.lang.Error
- java.lang.Exception
- java.lang.RuntimeException
- Unchecked Exception
- Other Exception
- Checked Exception
- java.lang.Throwable
An exception is ultimately also a class. Therefore, every Exception class inherits from the Throwable class, and Throwable is a child class of the top-level Object class.
The classes that inherit from Throwable are Error and Exception. Error is mainly a class for hardware-related exception handling and represents serious system-level errors. Examples include memory problems (OutOfMemoryError), stack overflow, and thread interruption. For this kind of exception, it is generally more appropriate to resolve the problem by changing the system rather than handling it in code.
Exception can be broadly divided into exceptions that inherit RuntimeException and exceptions that do not. The reason for dividing them based on RuntimeException is whether exception declaration is required. Exceptions related to RuntimeException usually do not cause a major problem even if they are not declared separately, because the effort spent declaring them can be greater than the benefit gained. It is more efficient to leave this kind of exception handling to the JVM.
Exceptions related to RuntimeException, like Error, are often not declared separately. The effort required one by one is greater than the efficiency gained by declaring them.
Checked Exception and Unchecked Exception
- Checked Exception
- Must be handled.
- Does not trigger transaction rollback.
- Does not inherit RuntimeException. (X)
- IOException, SQLException
- Unchecked Exception
- Does not have to be handled.
- Triggers transaction rollback.
- Inherits RuntimeException. (O)
- NullPointerException, IllegalArgumentException
Basic Exception Handling: try~catch~finally
To handle exceptions directly inside a method, use the try, catch, and finally keywords.
try {
// try block
} catch (exceptionType1 parameter1) {
// try exception handling block 1
} catch (exceptionType2 parameter2) {
// try exception handling block 2
}
...
} catch (exceptionTypeN parameterN) {
// try exception handling block N
} finally {
// finally block
}
The try block specifies a range where an exception may occur. You can designate the part of the program where an exception may occur during execution as a try block. A try block must have at least one catch block.
The catch block runs when an exception occurs in the try block. The exception-type parameter of the catch block contains information about the exception that occurred in the try block. Various exceptions can occur in a try block, and multiple catch blocks can be specified according to the kinds of exceptions.
The finally block is optional and always runs regardless of whether an exception occurs. In other words, when the try block runs, the finally block runs whether an exception occurs or not.
It is often used when an object is created and must be closed. For example, it is used when a file is opened and must be closed, or when a database connection is opened and must be closed.
package com.devkuma.tutorial.exception;
public class TryCatch {
public static void main(String[] args) {
try {
int i = Integer.parseInt(args[0]);
System.out.println("i=" + i);
} catch (NumberFormatException e) {
System.out.println("NumberFormatException");
throw e;
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("ArrayIndexOutOfBoundsException");
throw e;
}
}
}
Multiple Exceptions in Enhanced try~catch
As an enhancement in JDK 1.7, try~catch can handle multiple exceptions together. This is possible for exceptions in different inheritance hierarchies. For example, NumberFormatException and ArrayIndexOutOfBoundsException can be handled together.
Before JDK 1.7, exceptions were handled as follows.
...omitted...
} catch (NumberFormatException e) {
System.out.println("NumberFormatException");
throw e;
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("ArrayIndexOutOfBoundsException");
throw e;
}
Since JDK 1.7, the following form has been possible.
...omitted...
} catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
System.out.println("Exception");
throw e;
}
Passing Exception Handling On: throws
There are two ways to handle exceptions: handling them inside a method with a try~catch statement, or passing the occurred exception to the method that called it.
This exception handling approach is useful when all handling should be done in one method, and exceptions are declared using the throws keyword. If there are many exceptions to handle, list them separated by commas.
public void method() throws exceptionClass[, exceptionClass...]
Artificially Throwing Exceptions: throw
When an exception occurs while a Java program is running, the JVM automatically creates the corresponding exception object and then looks for a catch routine to handle the exception.
Exceptions may occur during execution by the JVM, but a user program can also intentionally throw an exception. Java uses the throw keyword to intentionally throw an exception.
throw exceptionObject;
Or:
throw new exceptionClass(parameter);
User-Defined Exception Classes
In addition to the exception classes provided by Java, users can also create their own classes. To create a user-defined exception class, inherit from the Exception class and create a new exception class.