Java Language Introduction


Example

Exceptions are errors which occur when a program is executing. Consider the Java program below which divides two integers.

class Division {
    public static void main(String[] args) {
 
        int a, b, result;
 
        Scanner input = new Scanner(System.in);
        System.out.println("Input two integers");
 
        a = input.nextInt();
        b = input.nextInt();
 
        result = a / b;
 
        System.out.println("Result = " + result);
    }
}

Now we compile and execute the above code, and see the output for an attempted division by zero:

Input two integers
7 0
Exception in thread "main" java.lang.ArithmeticException: / by zero 
    at Division.main(Disivion.java:14)

Division by zero is an invalid operation that would produce a value that cannot be represented as an integer. Java deals with this by throwing an exception. In this case, the exception is an instance of the ArithmeticException class.

Note: The example on creating and reading stack traces explains what the output after the two numbers means.

The utility of an exception is the flow control that it allows. Without using exceptions, a typical solution to this problem may be to first check if b == 0:

class Division {
    public static void main(String[] args) {
 
        int a, b, result;

        Scanner input = new Scanner(System.in);
        System.out.println("Input two integers");
 
        a = input.nextInt();
        b = input.nextInt();
 
        if (b == 0) {
            System.out.println("You cannot divide by zero.");
            return;
        }

        result = a / b;
 
        System.out.println("Result = " + result);
    }
}

This prints the message You cannot divide by zero. to the console and quits the program in a graceful way when the user tries to divide by zero. An equivalent way of dealing with this problem via exception handling would be to replace the if flow control with a try-catch block:

...

a = input.nextInt();
b = input.nextInt();
 
try {
    result = a / b;
}
catch (ArithmeticException e) {
    System.out.println("An ArithmeticException occurred. Perhaps you tried to divide by zero.");
    return;
}
 
...  

A try catch block is executed as follows:

  1. Begin executing the code in the try block.
  2. If an exception occurs in the try block, immediately abort and check to see if this exception is caught by the catch block (in this case, when the Exception is an instance of ArithmeticException).
  3. If the exception is caught, it is assigned to the variable e and the catch block is executed.
  4. If either the try or catch block is completed (i.e. no uncaught exceptions occur during code execution) then continue to execute code below the try-catch block.

It is generally considered good practice to use exception handling as part of the normal flow control of an application where behavior would otherwise be undefined or unexpected. For instance, instead of returning null when a method fails, it is usually better practice to throw an exception so that the application making use of the method can define its own flow control for the situation via exception handling of the kind illustrated above. In some sense, this gets around the problem of having to return a particular type, as any one of multiple kinds of exceptions may be thrown to indicate the specific problem that occurred.

For more advice on how and how not to use exceptions, refer to Java Pitfalls - Exception usage