How do I catch multiple exceptions?

If a try block can throw several kind of exceptions, and you want to handle each exception differently, you can put several catch blocks to handle it.

package org.kodejava.basic;

public class MultipleCatchExample {
    public static void main(String[] args) {
        int[] numbers1 = {1, 2, 3, 4, 5};
        int[] numbers2 = {1, 2, 3, 4, 5, 6};

        try {
            // This line throws an ArrayIndexOutOfBoundsException
            MultipleCatchExample.printResult(numbers1);

            // This line throws an ArithmeticException
            MultipleCatchExample.printResult(numbers2);
        } catch (ArithmeticException e) {
            e.printStackTrace();
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        } finally {
            System.out.println("Finally block is always executed.");
        }
    }

    /**
     * Divide the given first number by the second number.
     *
     * @param x the first number.
     * @param y the second number.
     * @return the result of division.
     */
    private static int divide(int x, int y) {
        return x / y;
    }

    /**
     * Print the output result of divide operation by calling the
     * divide() method.
     *
     * @param numbers integer arrays of the divided number
     * @throws ArrayIndexOutOfBoundsException when an exception
     *                                        occurs.
     */
    private static void printResult(int[] numbers) {
        int x, z, y = 1;
        for (int i = 0; i < 6; i++) {
            x = numbers[i];
            if (i == 5) {
                y = 0;
            }
            z = MultipleCatchExample.divide(x, y);
            System.out.println("z = " + z);
        }
    }
}

How do I use the throws keyword to declare method exceptions?

The throws keyword is used in method declarations to specify which exceptions are not handled within the method body but rather passed to the next higher level of the program. All uncaught exceptions in a method that are not instances of RuntimeException must be declared using the throws keyword.

In the example below you could see that the getConnection() method can cause a ClassNotFoundException when the driver class cannot be found and an SQLException when it fails to initiate a connection to database.

On the other end, the main() method which call the getConnection() method should catch all the exception throws by the getConnection() method in its body.

package org.kodejava.basic;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class ThrowsExample {
    public static void main(String[] args) {
        Connection connection = null;

        try {
            // Might throw ClassNotFoundException or SQLException
            // that's why we should catch them.
            connection = getConnection();
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        } finally {
            System.out.println("Finally is always executed");
            System.out.println("Close connection");
            try {
                if (connection != null && !connection.isClosed()) {
                    connection.close();
                }
            } catch (SQLException e) {
                System.out.println("Sql exception caught");
            }
        }
    }

    /**
     * Get database connection.
     *
     * @return Connection
     * @throws ClassNotFoundException when driver class is not found.
     * @throws SQLException           when database error occurs.
     */
    private static Connection getConnection()
            throws ClassNotFoundException, SQLException {

        Class.forName("com.mysql.cj.jdbc.Driver");
        return DriverManager.getConnection("jdbc:mysql://localhost/kodejava",
                "root", "");
    }
}

Without adding the database driver it will get the following exception:

java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:375)
    at org.kodejava.basic.ThrowsExample.getConnection(ThrowsExample.java:40)
    at org.kodejava.basic.ThrowsExample.main(ThrowsExample.java:14)
Finally is always executed
Close connection

How do I handle exceptions using try-catch block?

An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program’s instructions. When an abnormal situation occurs within a method, an Exception object is thrown. This object contains information about the error or unusual problems that occur.

Creating an exception object and handing it to the runtime system is called throwing an exception. If you want to deal with the exceptions where they occur, you can include three kinds of code blocks in a method to handle them. try, catch, and finally blocks.

  • The try block encloses code that may give rise to one or more exceptions.
  • The catch block encloses code that is intended to handle exceptions to a particular type that may be thrown in the associated try block.
  • The code in a finally block is always executed before the method ends, regardless of whether any exceptions are thrown in the try block.
package org.kodejava.basic;

public class ExceptionHandlerExample {

    public static void main(String[] args) {
        int x = 1, y = 0, z = 0;

        try {
            // divide by 0 will throw an exception
            z = ExceptionHandlerExample.divide(x, y);
            System.out.println("z = " + z);
        } catch (ArithmeticException e) {
            e.printStackTrace();
        } finally {
            System.out.println("Finally block is always executed.");
        }
    }

    /**
     * Divide the given first number by the second number.
     *
     * @param x the first number.
     * @param y the second number.
     * @return the result of division.
     * @throws RuntimeException when an exception occurs.
     */
    private static int divide(int x, int y) throws RuntimeException {
        return x / y;
    }
}

Here is what happening when we run the program:

java.lang.ArithmeticException: / by zero
    at org.kodejava.basic.ExceptionHandlerExample.divide(ExceptionHandlerExample.java:28)
    at org.kodejava.basic.ExceptionHandlerExample.main(ExceptionHandlerExample.java:10)
Finally block is always executed.

How do I log an exception?

In this example you can see how we can log an exception when it occurs. In the code below we are trying to parse an invalid date which will give us a ParseException. To log the exception we call the Logger.log() method, passes the logger Level, add some user-friendly message and the Throwable object.

package org.kodejava.util.logging;

import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParseException;

public class LoggingException {
    private static Logger logger =
            Logger.getLogger(LoggingException.class.getName());

    public static void main(String[] args) {
        DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
        df.setLenient(false);

        try {
            // Try to parse a wrong date.
            Date date = df.parse("12/30/1990");

            System.out.println("Date = " + date);
        } catch (ParseException e) {
            // Create a Level.SEVERE logging message
            if (logger.isLoggable(Level.SEVERE)) {
                logger.log(Level.SEVERE, "Error parsing date", e);
            }
        }
    }
}

The code above will produce the following log message.

Oct 07, 2021 8:21:44 PM org.kodejava.util.logging.LoggingException main
SEVERE: Error parsing date
java.text.ParseException: Unparseable date: "12/30/1990"
    at java.base/java.text.DateFormat.parse(DateFormat.java:399)
    at org.kodejava.util.logging.LoggingException.main(LoggingException.java:20)

How do I get an exception stack trace message?

In this example we use the java.io.StringWriter and java.io.PrintWriter class to convert stack trace exception message to a string.

package org.kodejava.io;

import java.io.StringWriter;
import java.io.PrintWriter;

public class StackTraceToString {
    public static void main(String[] args) {
        try {
            int result = 10 / 0;
        } catch (Exception e) {
            // Create a StringWriter and a PrintWriter both of these object
            // will be used to convert the data in the stack trace to a string.
            StringWriter stringWriter = new StringWriter();
            PrintWriter printWriter = new PrintWriter(stringWriter);

            // Instead of writing the stack trace in the console we write it
            // to the PrintWriter, to get the stack trace message we then call
            // the toString() method of StringWriter.
            e.printStackTrace(printWriter);

            System.out.println("Error = " + stringWriter);
        }
    }
}

This code snippet print the following output:

Error = java.lang.ArithmeticException: / by zero
    at org.kodejava.io.StackTraceToString.main(StackTraceToString.java:9)