Exception is an unwanted or unexpected event, which occurs during the execution of a program, (i.e. at run time, that disrupts the normal flow of the program’s instructions). Exceptions can be caught and handled by the program.

In Java, when an exception occurs within a method, it creates a Throwable object, the Throwable class is the superclass of all errors and exceptions in the Java language. This object is called an exception object, it contains information about the exception, such as the name and description of the exception and the state of the program when the exception occurred (e.g. cause, detailMessage, and stackTrace). Every time an exception occurs in a method, we say that the method throws an exception.

More about Throwable and Exception classes in Exception Hierarchy.

Types of exceptions

Checked exception

Checked exceptions are also known as compile-time exceptions because these exceptions are checked by the compiler during the compilation process. If a method can throw a checked exception, it must either handle it with a try-catch block or declare it using the throws keyword. The compiler enforces this rule, and if it’s not followed, a compilation error will occur. In many IDEs, the source where the exception can occur will be highlighted (often with a red squiggly underline) to notify the programmer before the actual compilation error is shown. Any class that is a subclass of Throwable, except those that are also subclasses of RuntimeException or Error is considered a checked exception. (learn more in Exception Hierarchy)

Unchecked exception

Unchecked exceptions, AKA runtime exceptions, are not checked by the compiler at compile-time, these include programming bugs, logic errors, or improper use of an API. Examples of unchecked exceptions include NullPointerException and ArrayIndexOutOfBoundsException. Unchecked exceptions include RuntimeException and its subclasses, as well as Error and its subclasses.

Error

Errors refer to issues that are external to the application and are often caused by a shortage of system resources. They are usually more serious than exceptions and application is not expected to handle them as they are outside the control of the program. Examples include StackOverflowError and LinkageError (error from JVM class loader sub-system).

Exception handling

Exception Handling in Java is one of the effective means to handle the runtime errors so that the regular flow of the application can be preserved. Whenever an exception occurs the Java runtime looks for a block of code in that method for handling the exception.

This is an error message output in the terminal when running a Java program, the stack trace information is printed.

Exception in thread "main" java.lang.NullPointerException
    at Printer.printString(Printer.java:13)
    at Printer.print(Printer.java:9)
    at Printer.main(Printer.java:19)

This program throws a NullPointerException, the NullPointerException is a class declared in the package java.lang.

  • When an exception is thrown, the Java runtime attempts to find exception handler through stack trace (back trace) before the program aborted
  • If the stack is exhausted and no exception handler is found, the program terminates with exit code 1 and the stack trace information will be displayed in the terminal

Exception handling approach

In Java you handle exceptions using the following approaches:

  • Try-catch block
  • Finally block
  • Throws keyword (ducking exception)
  • Custom exception handling by creating your own exception class

Try-catch block

Place the code that throw an exception inside the try block, the catch block is used to handle the exception. If there is an exception found, the runtime will pass the control to the corresponding catch block for handling that type of exception; every try block is followed by a catch block. In the catch parenthesis we specify the type of exception to catch follow by a name of the exception object normally e or ex (short for exception), the catch block catches the exception and statement inside the catch block is executed. Inside catch block we can print the exception message (getMessage()) or perform other operations using methods from the specific exception class or methods inherited from theThrowable class. Below is the exception handling using try-catch block for uncheck exception.

public static void main(String[] args) {
	try {
		int result = divide(10, 0);
		System.out.println("Result: " + result);
	} catch (ArithmeticException e) {
		System.err.println("Cannot divide by zero: " + e.getMessage());
	}
	
	public static int divide(int a, int b) {
		return a / b; // Can throw ArithmeticException
	}
}

Catch multiple exceptions Use pipes or multiple catch clauses to catch multiple exceptions.

public static void show() {
	try {  
	    var reader = new FileReader("text_file.txt");  
	    var value = reader.read();  
	    new SimpleDateFormat().parse("");  
	} catch (IOException | ParseException exception) {  
	    System.err.println("Cannot read data");  
	}
}

Finally keyword The finally clause will aways execute regardless whether there is an exception thrown or handled by the catch block. It is often used to close resources to prevent resource leak after using it.

public calss Demo {
	public static void main(String[] args) throws IOException {
		int num = 0;
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			System.out.println("Enter a number:");
			int num = Integer.parseInt(br.readLien()); 
			System.out.println(num);
		}
		finally {
			br.close(); // always close resources after use
		}
	}
}

Ducking exception

Ducking an exception refers to propagating an exception to the caller instead of handling it in the current method. This is achieved using the throws keyword in the method signature.

public class ExceptionDuckingExample {
    // This method declares it may throw an exception
    // And it will duck the exception to its caller
    public static void riskyMethod() throws Exception {
        // Simulating an exception
        throw new Exception("Something went wrong!");
    }
 
    // This method again does not handle the exception, it ducks it
    public static void anotherMethod() throws Exception {
        riskyMethod(); // It may throw exception
    }
	
	// This method handles the exception
    public static void main(String[] args) {
        try {
            anotherMethod(); 
        } catch (Exception e) {
            System.out.println("Caught exception: " + e.getMessage());
        }
    }
}
 

Custom exception

You can create a custom exception class by extending the Exception class for checked exceptions or RuntimeException for unchecked exceptions.

// Define a custom checked exception by extending Exception
public class InvalidAgeException extends Exception {
    // Constructor with a custom error message
    public InvalidAgeException(String message) {
        super(message);
    }
}
public class Main {
    // Method that throws the custom exception
    public static void checkAge(int age) throws InvalidAgeException {
        if (age < 18) {
            throw new InvalidAgeException("Age must be 18 or older.");
        }
    }
    
    public static void main(String[] args) {
        try {
            checkAge(16); // This will trigger the exception
        } catch (InvalidAgeException e) {
            System.out.println("Caught Exception: " + e.getMessage());
        }
    }
}
 

Back to parent page: Java Standard Edition (Java SE) and Java Programming

Web_and_App_Development Programming_Languages Java Exception

Reference: