Core Java

Exception Handling in Java – How to throw an exception

In this article, we will explain the Exception Handling in Java. If you want to learn more about how to throw an exception in Java, you can also check the Java Exceptions List Example.

You can also check this tutorial in the following video:

Java Exceptions Handling Tutorial – video

1. What are Exceptions?

Exceptions are events that occur during the execution of programs that disrupt the normal flow of instructions (e.g. divide by zero, array access out of bound, etc.).

Exception objects can be thrown and caught.

2. Types of exceptions

There are two types of exceptions in Java: checked (compile time) exceptions and unchecked (runtime) exceptions. For clarity, we’ll also discuss how errors are different than exceptions in Java.

2.1 Checked exception (compile time exception)

Checked exceptions must be caught and handled during compile time. If the compiler does not see a try or catch block or throws keyword to handle a checked exception, it throws a compilation error. Checked exceptions are generally caused by faults outside code like missing files, invalid class names, and networking errors. For example, FileNotFoundException is a checked exception.

2.2 Unchecked exception (runtime exception)

Unchecked exceptions do not need to be explicitly handled; they occur at the time of execution, also known as run time. These exceptions can usually be avoided by good coding practices. They are typically caused by programming bugs, such as logic errors or improper use of APIs. These exceptions are ignored at the time of compilation. For example division by 0 causes ArithmeticException which is an unchecked exception.

2.3 Custom exceptions

Java’s built-in exceptions don’t always provide the information we need. So, we sometimes need to supplement these exceptions with our own. If an exception occurs in your application, you need to recover and make the user know about it. A custom exception gives you more control to provide extra data about the problem and to handle the exception in your code.

The best practice is to extend the java.lang.Exception class with a new class. The new class requires a constructor that will take a string as the error message—it is called the parent class constructor.

For example, let’s say a program fails to connect to a database. You could use a custom exception to collect information like the database URL, username, password, etc.

See example ThrowExcep03:

HandledException.java

public class HandledException extends Exception {
    private String code;

    public HandledException(String code, String message) {
        super(message);
        this.setCode(code);
    }

    public HandledException(String code, String message, Throwable cause) {
        super(message, cause);
        this.setCode(code);
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
}

As you see our custom exception HandledException extends Exception class. Now in the MainClass we will try to connect to a Database:

MainClass.java

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

public class MainClass {
    
    public static void main(String[] args) {
        try {
            makeDatabaseConnection();
        } catch (HandledException e) {
            System.out.println("Code: " + e.getCode() + " Exception Message : " + e.getMessage());
        }
    }

    static void makeDatabaseConnection() throws HandledException {
        String dbURL = "jdbc:sqlserver://localhost\\sqlexpress";
        String userName = "JavaCode";
        String password = "Geeks";
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(dbURL, userName, password);
        } catch (SQLException e) {
            throw new HandledException("Database Exception" , "Failed to connect to database", e);
        }
    }
}

As you see, if the connection fails, in the catch block, we can write this information and display a basic message to the user like “failed to connect to the database.”

The output is:

Code: Database Exception Exception Message : Failed to connect to database

3. throw and throws in Java

3.1 throw

The throw keyword in Java is used to explicitly throw an exception from a method or any block of code. We can throw either checked or unchecked exception. The throw keyword is mainly used to throw custom exceptions.

Syntax:

throw Instance
Example:
throw new ArithmeticException("/ by zero");

But this exception i.e, Instance must be of type Throwable or a subclass of Throwable. For example, Exception is a subclass of Throwable and user-defined exceptions typically extend Exception class.

The flow of execution of the program stops immediately after the throw statement is executed and the nearest enclosing try block is checked to see if it has a catch statement that matches the type of exception. If it finds a match, control is transferred to that statement otherwise next enclosing try block is checked and so on. If no matching catch is found then the default exception handler will halt the program.

In example ThrowExcep01 I will show how we throw and catch an unchecked exception:

MainNoThrows.java

import java.util.Scanner;

public class MainNoThrows {

    public static int divide (int num1, int num2){

        int result;
        try
        {
            result = num1/num2;
        }
        catch(ArithmeticException e)
        {
            System.out.println("Caught inside divide().");
            throw e; // rethrowing the exception
        }

        return result;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("Enter first number:");
        int num1 = scanner.nextInt();

        System.out.println("Enter second number:");
        int num2 = scanner.nextInt();

        try
        {
            int result = divide(num1, num2);
            System.out.println("The result is:" + result);
        }
        catch(ArithmeticException e)
        {
            System.out.println("Caught in main.");
        }
    }
}

As you see, if we enter zero for the second number we will get the ArithmeticException exception:

The output is:

Enter first number:
1
Enter second number:
0
Caught inside divide().
Caught in main.

3.2 throws

The “throws” keyword is used to declare that a method may throw one or some exceptions. The caller to these methods has to handle the exception using a try-catch block.

Syntax:

type method_name(parameters) throws exception_list
exception_list is a comma separated list of all the 
exceptions which a method might throw.

In a program, if there is a chance of rising an exception then compiler always warn us about it and we should handle that checked exception, Otherwise, we will get a compile-time error saying unreported exception XXX must be caught or declared to be thrown. To prevent this compile-time error we can handle the exception in two ways:

  1. By using try-catch
  2. By using throws keyword

We can use throws keyword to delegate the responsibility of exception handling to the caller (It may be a method or JVM) then the caller method is responsible to handle that exception.

As you see in ThrowsExcep01 example:

exception Handling in Java - Unhandled exception
Unhandled exception

So if you run the program, you will get this error:

exception Handling in Java - Unreported exception
Unreported exception

Explanation : In the above program, we are getting a compile-time error because there is a chance of exception if the main thread is going to sleep, other threads get the chance to execute main() method which will cause InterruptedException.

So we should use the throws keyword for main():

MainWithThrows.java

public class MainWithThrows {

    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(10000);
        System.out.println("Hello Java Code Geeks.");
    }
}

The output is:

Hello Java Code Geeks.

Let’s see another example, ThrowExcep02:

Main.java

import java.io.FileWriter;
import java.io.IOException;

public class Main {

    public static void writeFile (String filePath) {
        FileWriter file = null;
        try {
            file = new FileWriter(filePath);
            file.write("Guru99");
            file.close();
        } catch (IOException e) {
            System.out.println("Caught inside writeFile().");
        }
    }

    public static void main(String[] args) {

        String filePath = "c:\\Data.txt";

        writeFile(filePath);
    }
}

The write() method throws IOException (a checked exception) so we should handle this exception using try & catch. If you do not handle the exception in a try-catch block, compiling will fail.

If you run the program without having the file in the defined path you will see this message:

The file does not exist!

So we will first create an empty text file with name Data.txt in our C drive. Now the program runs successfuly:

Process finished with exit code 0

3.3 What are the difference between throw and throws?

exception Handling in Java - Comparing throw and throws
Comparing throw and throws

4. When (Not) to throw Exceptions?

Methods must not throw RuntimeExceptionException, or Throwable. Handling these exceptions requires catching RuntimeException, which is disallowed by ERR08-J. Do not catch NullPointerException or any of its ancestors. Moreover, throwing a RuntimeException can lead to subtle errors; for example, a caller cannot examine the exception to determine why it was thrown and consequently cannot attempt recovery.

Methods can throw a specific exception subclassed from Exception or RuntimeException. Note that it is permissible to construct an exception class specifically for a single throw statement.

See example NotThrowExcep01 which is a noncompliant code:

The isCapitalized() method in this example accepts a string and returns true when the string consists of a capital letter followed by lowercase letters. The method also throws a RuntimeException when passed a null string argument.

Main.java

public class Main {

    static boolean isCapitalized(String s) {
        if (s == null) {
            throw new RuntimeException("Null String");
        }
        if (s.equals("")) {
            return true;
        }
        String first = s.substring(0, 1);
        String rest = s.substring(1);
        return (first.equals(first.toUpperCase()) &&
                rest.equals(rest.toLowerCase()));
    }

    public static void main(String[] args) {

        String str_not_null = "Java";
        String str_is_null = null;

        System.out.println(str_not_null + "is Capitalized? " + isCapitalized(str_not_null));
        System.out.println(str_is_null + "is Capitalized?" + isCapitalized(str_is_null));
    }
}

When you run the program you will get this result:

RuntimeException

A calling method must also violate ERR08-J. Do not catch NullPointerException or any of its ancestors to determine whether the RuntimeException was thrown.

So the compliant solution is shown in NotThrowExcep02:

Main.java

public class Main {

    static boolean isCapitalized(String s) {
        if (s == null) {
            throw new NullPointerException();
        }
        if (s.equals("")) {
            return true;
        }
        String first = s.substring(0, 1);
        String rest = s.substring(1);
        return (first.equals(first.toUpperCase()) &&
                rest.equals(rest.toLowerCase()));
    }

    public static void main(String[] args) {

        String str_not_null = "Java";
        String str_is_null = null;

        System.out.println(str_not_null + "is Capitalized? " + isCapitalized(str_not_null));
        System.out.println(str_is_null + "is Capitalized?" + isCapitalized(str_is_null));
    }
}

Note that the null check is redundant; if it were removed, the subsequent call to s.equals("") would throw a NullPointerException when s is null. However, the null check explicitly indicates the programmer’s intent.

Now let’s see other examples of noncompliant and compliant codes:

Noncompliantcode example specifies the Exception class in the throws clause of the method declaration

private void myFunction() throws Exception {
  //...
}

compliant solution declares a more specific exception class in the throws clause of the method declaration

private void myFunction() throws IOException {
  //...
}

There are multiple reasons why you should not use exceptions:

  1. Exceptions are not designed for this. It will be confusing. It looks like a failure scenario but it’s just some sort of flow control.
  2. Exceptions are hard to follow. It looks like you are using just another form of a goto statement. I don’t have to clarify why using goto is a bad idea, do I?
  3. Exceptional exceptions? If you use exceptions for normal situations, how do you signal unusual situations?
  4. Exceptions are slow. Because exceptions only rarely occur, performance is not a priority for the implementers of compilers nor the designers of the language. Throwing and catching exceptions is inefficient and many times slower than a simple check of a return value or a state field.

5. Summary

To summarize, here are some recommendations regarding the Exception Handling in Java:

  • Don’t use exceptions to signal something completely normal.
  • Don’t use exceptions to control your normal application flow.
  • Use return values or state fields for flow control instead.

6. Download the Source Code

That was an example of Exception Handling in Java.

Download
You can download the full source code of this example here: Exception Handling in Java – How to throw an exception

Last updated on Feb. 27th, 2020

Firouzeh hejazi

A self-motivated and hard-working developer with more than 4 years of extensive experience in developing software in java platforms. A multi-skilled and problem-solving engineer who has participated in implementing a range of applications in different roles. Possess a MSc in Knowledge Engineering and Decision Science.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button