try-catch-finally in Java

try-catch-finally in Java | In this post, we will discuss, how we can handle the exception using try-catch block and the role of the finally block. Also see:- Exception Handling in Java

Without try-catch

public class Test {
   public static void main(String[] args) {
      System.out.println("Statement1");
      System.out.println(9/0);
      System.out.println("Statement3");
   }
}

Statement1
Exception in thread “main” java.lang.ArithmeticException: / by zero
at Test.main(Test.java:4)

It is an abnormal termination.

public class Test {
   public static void main(String[] args) {
      System.out.println("Statement1");
      try {
         System.out.println(9/0);
      } catch (ArithmeticException e) {
         System.out.println(9/1);
      }
      System.out.println("Statement3");
   }
}

Output:-

Statement1
9
Statement3

It is normal termination.

It is highly recommended to handle exceptions. The code which may raise an exception is called risky code. We have to define the code inside the try-catch block & corresponding handling code we have to define in the catch block.

try {
   // risky code
} catch(Exception e) {
   // Handling code
}

Control flow in try-catch

  • Within the try block if anywhere exception is raised then the rest of the try block won’t be executed even though we handled that exception hence within the try block we have to take only risky code and the length of the try block should be as less as possible.
  • In addition, to try block, there may be a chance of raising of an exception inside catch & finally blocks.
  • If any statement which is not part of the try-catch block & raises an exception then it is always abnormal termination.
try {
   statement1;
   statement2;
   statement3;
} catch(Exception e) {
   statement4;
}
statement5;

Case-1:- If there is no exception. Then output (normal termination),
statement1
statement2
statement3
statement5

Case-2:- If an exception is raised at “statement2” & corresponding catch block is matched? Then output (normal termination),
Statement1
statement4
statement5

Case-3:- If an exception is raised at “statement2” & corresponding catch block is not matched. Then output (abnormal termination),
statement1

Case-4:- If an exception is raised at “statement4” or “statement5”? => Then it will be always abnormal termination.

Methods to Print Exception Information

Throwable class defines the following methods to print exception information, learn more:- Different ways to get the exception message

MethodPrintable format
printStackTrace()Name of exception; Description; Stack trace
toString()Name of exception; Description
getMessage()Description

try with multiple Catch blocks

The way of handling an exception varies from exception to exception. Hence, for every exception type it is highly recommended to take a separate catch block i.e. try with multiple catch blocks is also possible & recommended to use.

// worst programming practice
try {
   // risky code
} catch(Exception e) {
   // Handling code
}
// best programming practice
try {
   // risky code
} catch(ArithmeticException ae) {
   // perform alternative arithmetic operations
} catch(SQLException e) {
   // Use MySQL database instead of Oracle database
} catch(Exception e) {
   // Use local file instead of remote file
} catch(Exception e) {
   // default exception Handling code
}

Important point while using multiple catch block

try {
   // risky code
} catch(Exception e) {
   // exception Handling code
} catch(ArithmeticException ae) {
   // exception Handling code
} 

Compile time error:- Exception java.lang.ArithmeticException has already been caught.

try {
   // risky code
} catch(ArithmeticException ae) {
   // exception Handling code
} catch(Exception e) {
   // exception Handling code
}

If try with multiple catch blocks present then the order of catch blocks is very important. We have to take the child first & then the parent otherwise we will get compile time error saying:- Exception Xxx has already been caught.

try {
   // risky code
} catch(ArithmeticException ae) {
   // exception Handling code
} catch(ArithmeticException ae) {
   // exception Handling code
}

Compile time error:- Exception java.lang.ArithmeticException has already been caught. We can’t declare 2 catch blocks for the same exception otherwise we will get a compile-time error.

Example-1:-

// valid
try {
} catch (Exception e) {
}

Example-2:-

// valid
try {
} catch (X e) {
} catch (Y e) {
}

Example-3:-

// invalid
try {
} catch (X e) {
} catch (X e) {
}

Both catch blocks handle the same exception. Compile time error:- exception X has already been caught.

finally Block

Difference between final, finally, and finalize?
Final:- The final is a modifier applicable for classes, methods, and variables. If a class is declared as final then we can’t extend that class i.e. we can’t create a child class for that class i.e. inheritance is not possible for the final class. If a method is final then we can’t override that method in the child class. If a variable is declared as final then we can’t perform re-assignment for that variable.

Finally:- The finally is a block always associated with try-catch to maintain cleanup code.

try {
   // risky code
} catch(Exception e) {
   // handling code
} finally {
   // cleanup code
}

The specialty of the finally block is:- It will be executed always irrespective of whether the exception is raised or not raised or whether handled or not handled.

finalize():- The finalize() is a method always invoked by the garbage collector just before destroying an object to perform cleanup activities. Once the finalize() method completes immediately garbage collector destroys that object.

The finally block is responsible for performing cleanup activity related to the try block i.e. whatever resources we opened as a part of the try block will be closed inside the finally block. Whereas the finalize() method is responsible for performing cleanup activities related to the object i.e. whatever resources associated with the object will be deallocated before destroying an object by using finalize() method.

Various possible combinations of try-catch finally:-

  1. In try-catch-finally block order is important.
  2. Whenever we are writing try then compulsory we have to write either catch or finally otherwise we will get compile time error i.e. try without catch or finally is invalid.
  3. Whenever we are writing a catch block compulsory try block must be required i.e. catch without a try is invalid.
  4. Whenever we are writing finally block compulsory we should write try block i.e. finally without try is invalid.
  5. Inside try-catch & finally block, we can declare try-catch & finally blocks i.e. nesting of try-catch finally is allowed.
  6. For try-catch & finally blocks curly brackets are mandatory.

Example-4:-

// valid
try {
} catch (X e) {
} finally {
}

Example-5:- If we don’t want to handle any exception but before abnormal termination cleanup activity will be performed.

// valid
try {
} finally {
}

Example-6:-

// valid
try {
} catch (X e) {
}
try {
} catch (Y e) {
} 

Example-7:-

// valid
try {
} catch (X e) {
}
try {
} finally {
} 

Example-8:- Compile-time error:- try without catch (or) finally.

// invalid
try {
} 

Example-9:- Compile-time error:- finally without try

// invalid
finally {
} 

Example-10:- Compile-time error:- catch without try

// invalid
catch(X e) {
}

Example-11:- We will get 2 compile time error. Compile-time error:- try without catch or finally; Compile-time error: catch without try.

// invalid
try {
} 
System.out.println("Hello");
catch(X e) {
} 

Example-12:- Compile-time error:- catch without try.

// invalid
try {
} finally {
}
catch(X e) {
} 

The above code snippet will work as below.

try {
} finally {
}
// separate part 
catch(X e) {
} 

Example-13:- The second catch block becomes alone. Compile-time error:- catch without try.

// invalid
try {
} catch(X e) {
} 
System.out.println("Hello");
catch(Y e) {
} 

Example-14:- Compile-time error:- finally without try

// invalid
try {
} catch(X e) {
} 
System.out.println("Hello");
finally {
} 

Example-15:-

// valid
try {
   try {
   } catch (X e) {
   }
} catch(X e) {
}

Example-16:- In inner catch compile time error:- try without catch or finally

// invalid
try {
   try {
   } 
} catch(X e) {
}

Example-17:-

// valid
try {
   try {
   } finally {
   }
} catch(X e) {
}

Example-18:-

// valid
try {
} catch(X e) {
   try {
   } finally {
   }
}

Example-19:- Compile-time error:- finally without try

// invalid
try {
} catch(X e) {
   finally {
   }
}

Example-20:-

// valid
try {
} catch(X e) {
} finally {
   try {
   } catch(X e) {
   }
}

Example-21:- Compile-time error:- finally without try

// invalid
try {
} catch(X e) {
} finally {
   finally {
   }
}

Example-22:- There can be only one finally block for 1 try block. Compile-time error:- finally without try

// invalid
try {
} catch(X e) {
} finally {
} finally {
}

Example-23:- For try-catch-finally block, { } is mandatory.

// invalid
try
   System.out.println("try");
catch(X e) {
   System.out.println("catch");
} finally {
}

Example-24:-

// invalid
try {
}
catch(X e) 
   System.out.println("catch");
finally {
}

Example-25:-

// invalid
try {
}
catch(X e) {
}
finally {
   System.out.println("finally");
}

If you enjoyed this post, share it with your friends. Do you want to share more information about the topic discussed above or do you find anything incorrect? Let us know in the comments. Thank you!

Leave a Comment

Your email address will not be published. Required fields are marked *