Introduction and Return statements in try catch block


Introduction of Exception

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
10 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:

  • Begin executing the code in the try block.
  • 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).
  • If the exception is caught, it is assigned to the variable e and the catch block is executed.
  • 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


Return statements in try catch block

Although it's bad practice, it's possible to add multiple return statements in a exception handling block:

public static int returnTest(int number){
	try{
		if(number%2 == 0) throw new Exception("Exception thrown");
		else return x;
	}
	catch(Exception e){
		return 3;
	}
	finally{
		return 7;
	}
}

This method will always return 7 since the finally block associated with the try/catch block is executed before anything is returned. Now, as finally has return 7;, this value supersedes the try/catch return values.

If the catch block returns a primitive value and that primitive value is subsequently changed in the finally block, the value returned in the catch block will be returned and the changes from the finally block will be ignored.

The example below will print "0", not "1".

public class FinallyExample {
	public static void main(String[] args) {
		int n = returnTest(4);
 
		System.out.println(n);
	}
	public static int returnTest(int number) {
 
		int returnNumber = 0;
 
		try {
			if (number % 2 == 0)
				throw new Exception("Exception thrown");
			else
				return returnNumber;
		} catch (Exception e) {
			return returnNumber;
		} finally {
			returnNumber = 1;
		}
	}
}

Basic Programs