Java Exceptional Handling

To understand exceptional handling first it is required to understand the exception and why it should be handled in Java programs. Once we will understand this concept we can understand how to do exceptional handling. So we start with exception.

What is Exception

Exception means exceptional condition(s) or abnormal condition(s) which occurs during program execution. Generally, programmers write code in an idealized environment, considering- user will input only the correct values, the file will always be found on a defined location, the network will not break, etc, but in real-time or in production environment applications, this idealized environment is not possible each and every time, exceptional conditions can occur any time and due to such abnormal conditions, the normal flow of program or application can break.

When a normal program execution disrupts due to some errors/unwanted situation, is called Exception or Exceptional condition. Exceptions can occur due to many reasons(s).  I am listing a few of them.

  1. Due to incorrect or null value in the parameter.
  2. Due to the applied formula or condition, it was trapped in an infinite loop and the disk became full.
  3. Trying to put/get the value from an invalid index of an Array.
  4. Due to the use of incorrect path/file for processing.
  5. Due to typo mistakes like in code, for establishing connection syntactically wrong URL typed.
  6. Hardware device error like in the middle of the printout, the printer reached out of paper.
  7. Referring to the class which does not exist even in the imported library.

Why Exception Handling Needed

Suppose we write an application or programs in java. We are running our application, but it is not running completely and disrupting abnormally. Due to some of the unwanted situations or errors, our program is disrupted, and the error message which is displayed is not clear,  then it will be challenging to debug the issue to get to the root cause of the error.

It will be very time consuming to understand things. Even due to program disruption our application is not running properly and we are not sure about its behavior. To avoid such situations, in Java there is a mechanism called Exception handling.  Java provides Exception classes to handle the Exceptional situation through that we can handle the exceptional conditions.

When an exception occurs it is required to handle so that it will not impact any other related programs in an application.

What is Exception Handling in Java

Exception Handling is a mechanism to respond at the time of occurrence of exceptional conditions or exceptions during the program execution.

Due to the normal flow of program disruption, the method/program/Application terminates abnormally and does not return normal/any value.  Here Java provides one alternate exit path due to which it throws an Exception object encapsulating the error information. An Exception object is an instance of a class that is derived from the Throwable class.

For example, When you write java code as below to create a file it gives a compile-time exception by stating “Unhandled Exception type IOException”.

File testFile = new File("test.txt");

              boolean isExist = testFile.createNewFile();

              if(isExist) {

                System.out.println("it exists "+testFile.getPath());

              } else {

                System.out.println("does not exist");
              }

This method is giving a compile-time exception because in java some of the possible error-prone conditions are already known and forced the programmer to handle it. See this program and think- can’t it be possible that the file or file path which is mentioned might not exist then how the program will execute. Definitely it will break and would not execute. Considering such situations Java already gives this exception at compile time so that you can handle this exceptional scenario and can take the required action.

Exceptional Hierarchy

Throwable class is the main class of Exception, and all Exception classes are derived from this class. Error class and Exception class are its direct child classes. Objects which are the instance of this class or any of its subclass are thrown by Java Virtual Machine (JVM) or by Java statement(s).  In the catch clause, this class or its subclasses are used as argument types.

When an exceptional situation occurs, instances of two of its subclasses Error and Exception are created for relevant information such as stack trace data. It also contains a String type message object to provide information on the error.

The throwable class comes under java.lang package and has its two main subclasses Exception and Error.

Exception class further divided mainly into 2 categories: checked exceptions and unchecked exceptions (Runtime Exceptions).

The throwable class has one String variable for detailed information about the actual exception.

Error

An error is a subclass of Throwable class. It indicates a serious problem that a reasonable application should not try to catch. The error can not be recovered and the only solution to recover from error is to terminate the program. The error occurs at runtime so we can say it is an unchecked error. It occurs in the environment in which a program is running like OutOfMemoryError occurs when JVM runs out of memory and StackOverflowError occurs when stack overflows.

Example of Error exceptions are  StackOverflowError, OutOfMemoryError etc

Unchecked Exception (Runtime Exception)

Unchecked exceptions are the exceptions that occur at the time of execution of a program/application. That is why unchecked exceptions are also called runtime time exceptions. RuntimeExceptions or Unchecked exceptions can occur due to null object or due to use of Invalid index etc

Example of Unchecked or RuntimeException is NullPointerException, IllegalArgumentException, etc

Checked Exception

Checked Exceptions are the exceptions that are generated at the time of java code compilation. As these errors occur at the time of compilation so-called compile time exception also. In another word, we can say Any Exception which does not drive from Error class or RuntimeException class is known as checked Exception.

Checked exceptions cannot be ignored by the programmers as until unless compile-time error would not be resolved, the program would not be run. Checked exceptions can be handled easily as it comes at compilation. Compile-time errors could be like reference class is not found, the object is created but not initialized, etc Example of checked Exceptions are IOException, SQLException, etc.

Exceptions Types
Exceptions Types

Exception classes are also part of the inheritance hierarchy as other java classes.  The hierarchy is maintained to group similar kind of errors like ArrayIndexOutOfBoundsException which indicate passing arrayIndex value is out of range for the array and its parent class is IndexOutOfBoundsException

Exception Hierarchy

Exception Methods

In Java, the Exception class and its derived subclasses do not have any defined method. Same in the Error class and its derived subclasses, these also do not have any method defined. Error class and Exception classes and its derived subclasses have only constructor methods that further call the Throwable class constructor directly or indirectly.

All the methods are written in the Throwable class. All the exception classes are created to identify different kinds of exception scenarios and to handle it. All different exception classes and error classes help to identify the root cause of the problem.

Some of the useful methods of Throwable class are:

getMessage()

This method returns the detailed message String of current Throwable. Messages can be provided in the constructor while creating the exception.

Method syntax : public String getMessage()

getLocalizedMessage()

This method returns the localized description of the current Throwable. Subclasses can override this method to provide locale-specific messages.

Method syntax public String getLocalizedMessage()

getCause()

This method returns the cause of the exception. It returns null if the cause is nonexistent or unknown.

Method Syntax : public synchronized Throwable getCause()

public String toString()

This method returns the short description of Throwable in String format. In this method, the returned String contains the name of the Throwable class and localized message.

Method Sysntax : public String toString()

printStackTrace()

This method prints the current throwable and its backtrace information to the standard error stream.

Method Syntax: public void printStackTrace

printStackTrace(PrintStream s)

This method prints the current throwable and its backtrace information to the specified print stream.

Method Syntax : publicvoid printStackTrace(PrintStream s)

How to handle exception

Exception can be handled by using any of  below methods

  • By using try/Catching the exception(s)
  • By Using the throw clause
  • By using the throw/Throws clause
  • Finally block
  • Multiple catch block

By using try/Catch block

The try/catch block can be applied within a method. Java try block is followed by either catch or finally block or by both.

Try block is used to enclose the line(s) of code or block of code that needs to be tested or can cause any issue during execution.

The catch block is used to write line(s) of code that needs to be executed once any error occurs in the try block

So we can say, we write functional code in between the try block and exceptional handling code in the catch block. If any exception occurs in the try block on a particular line, then code written after that does not execute. It is recommended, code that would not cause any exception should be written out of try block.

Syntax :

Try {

//Line of code ...

} catch(<ExceptionName>  <exception object  name>)  {

  //Exception handling code
}

Sample Java code:

In this given sample code, we are trying to print the array value for index 1,5 and 3 through the main method. From the defined array ‘testNum,’ we can get the value from index 0-3, Value for index 5 is not defined in the array so that it will give an error. As in this program, we are using try/catch block to get the array values; the program will execute completely while an error will occur for index 5.

public class Test {
 
    public void getNumber(int indexNumber) {

          try {

          int[] testNum = {1, 2, 3,4};

          System.out.println(testNum[indexNumber]);

          } catch (ArrayIndexOutOfBoundsException e) {

                 System.out.println("Something went wrong."+e);

          }

          System.out.println("Statement after try catch block \n");

    }

     public static void main(String[] args) {

          try {
                 Test test = new Test();
                 test.getNumber(1);
                 test.getNumber(5);
                 test.getNumber(3);

          } catch (Exception e) {
                 e.printStackTrace();
          }
    }
}


Output:

2

Statement after try catch block
 
Something went wrong.java.lang.ArrayIndexOutOfBoundsException: 5
Statement after try catch block
 
4
Statement after try catch block

By using throws clause

Using the Throws keyword, we declare exception on a method. We can declare more than one exception on a method.  In this case, we do not handle the exception in the same method while throws the exception which could be handled in the calling method. Generally throws clause is used for a checked exception which needs to be handled at compile time

If you want that expected exception(s) should be handled in the calling method, then the Throws keyword is a good choice to be used. A very good example of the Throws clause is – when we create an object of FileOutputStream class to write in a file then you need to handle first already declared exception FileNotFoundException.

Example: In the given example, in getFile() we are not handling any exception using try/catch block while throwing to be handled in the calling method (here in main()). 

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;
 
public class Test {
 
    private void getFile(String data, String fileName) throws IOException, FileNotFoundException {

          File testFile = new File("E:/test/" + fileName);

          FileOutputStream fos = new FileOutputStream(testFile);

          fos.write(data.getBytes());

          System.out.println("data has been written in "+ 
fileName);

    }
 
    public static void main(String[] args) {

          Test test = new Test();

          try {

                 test.getFile("test", "test.txt");

                 test.getFile(null, "test1.txt");

          } catch (Exception e) {

                 System.out.println("some problem is coming while writing in file ");

                 e.printStackTrace();

          }

    }

}
 
 
Output:

data has been written in test.txt

java.lang.NullPointerException

some problem is coming while writing in file

    at com.java.test.exception.Test.getFile(Test.java:13)

    at com.java.test.exception.Test.main(Test.java:21)

By using throw clause

We use this throw keyword in exception handling to throw the exception explicitly inside the method. The throw statement starts with the throw keyword which is followed by an object that is instantiated from the class Throwable or any of its subclasses.

The Throwable object can be instantiated either by using the new operator or by the argument of the catch clause. The syntax for throw statement is something like

throw new IOException(“Something is wrong”)

Exception throw clause is generally used to throw custom Exception(s). Using the throw clause we can throw checked and unchecked both exceptions.

Example: In this example, we are trying to print the name from the string array bypassing the index value.  if we will not pass the correct index value, the code will not execute completely. So to handle this situation we are throwing the ArrayIndexOutOfBoundsException inside the method. Due to this, program execution is not breaking and we are able to get the name from arraylist as per passing index value. 

private String getName(int arrayIndex) {

          String[] nameList = { "Test1", "Anu", "Riya", "Ram" };

          int arrayLength = nameList.length;

          if (arrayIndex > arrayLength - 1) {

                 throw new ArrayIndexOutOfBoundsException(

                              "Index value " + arrayIndex + " is not valid to get the name. Please enter valid arrayIndex");

          }

          return nameList[arrayIndex];
 
    }
 
    void printName(int arrayIndex) {

          try {

          String name = getName(arrayIndex);

          System.out.println(name);

          } catch (Exception e) {

                 System.out.println(e.getMessage());

          }

    }
 
 
    public static void main(String[] args) {

          Test test = new Test();

          for (int i = 6; i >= 0; i--) {

                 test.printName(i);
          }
    }
 
Output:

Index value 6 is not valid to get the name. Please enter valid arrayIndex

Index value 5 is not valid to get the name. Please enter valid arrayIndex

Index value 4 is not valid to get the name. Please enter valid arrayIndex

Ram

Riya

Anu

Test1

Finally Block

Finally block is used to run some piece of code in any situation, whether in the normal execution of a program or in exceptional condition or we can say program written under try block or in the exceptional situation in the catch block. In the finally block we write important code which should be executed in any case during method calling such as closing connection etc

Example: Here in this example we are closing the file, in any situation either data is written successfully in a file or any exception is coming.

package com.java.test.exception;
 
import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;
 
public class Test {
 
    private void getFile(String data, String fileName) {
 
          FileOutputStream fos = null;

          try {

                 File testFile = new File("E:/test/" + fileName);

                 fos = new FileOutputStream(testFile);

                 fos.write(data.getBytes());

                 System.out.println("Data has been written in File " + fileName);

          } catch (FileNotFoundException fnfe) {

                 System.out.println("File not found at given location " + fileName + "  and Issue is " + fnfe.getMessage());

                 fnfe.printStackTrace();

          } catch (IOException ioe) {

                 System.out.println("some problem is coming while writing in file " + fileName + " " + ioe.getMessage());

                 ioe.printStackTrace();

          }  catch (NullPointerException npe) {

                 System.out.println("Some issue is coming while wrting in file " + fileName);

                 npe.printStackTrace();

          }finally {

                 try {

                        System.out.println("In finally block for file " + fileName + "\n");

                        fos.close();
 
                 } catch (Exception e) {
                      
  System.out.println("Exception is coming while closing fileoutputstream object");

                 }

          }

    }
 
    public static void main(String[] args) {

          Test test = new Test();

          test.getFile("test", "test.txt");

          test.getFile(null, "test1.txt");

          test.getFile("test2", "test2.txt");
    }

}


Output:

Data has been written in File test.txt

In finally block for file test.txt
 
Some issue is coming while writing in file test1.txt

java.lang.NullPointerException

    at com.java.test.exception.Test.getFile(Test.java:16)

    at com.java.test.exception.Test.main(Test.java:41)

In finally block for file test1.txt
 
Data has been written in File test2.txt

In finally block for file test2.txt

Multiple catch block

Multiple catch blocks are used when some piece of code has more than one situation in which error or exception can occur. So to handle the individual situation we use multiple catch block

  • At a time only one exception occurs and one exception handling catch block is executed.
  • All catch blocks must be ordered from most specific to most general, i.e. catch for ArithmeticException must come before catching for Exception. In other words, a catch block for child exceptions should be written before otherwise it will not be called.

Example: In this example, we are first catching FileNotFound then IOException because FileNotFound is a more specific and child class of IOException.  If we will catch IOException first Java will not allow us to catch FileNotFoundException.

Try {

}catch(Exception1 ex) {

} catch(Exception2 ex) {

}

package com.java.test.exception;
 
import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;
 
public class Test {
 
    private void getFile(String data, String fileName) {
 
          FileOutputStream fos = null;

          try {

                 File testFile = new File("E:/test/" + fileName);

                 fos = new FileOutputStream(testFile);

                 fos.write(data.getBytes());

                 System.out.println("Data has been written in File " + fileName);

          } catch (FileNotFoundException fnfe) {

                 System.out.println("File not found at given location " + fileName + "  and Issue is " + fnfe.getMessage());

                 fnfe.printStackTrace();

          } catch (IOException ioe) {

                 System.out.println("some problem is coming while writing in file " + fileName + " " + ioe.getMessage());

                 ioe.printStackTrace();

          }  catch (Exception ex) {

                 System.out.println("Some issue is coming while wrting in file " + fileName);

                 ex.printStackTrace();

          }

    }
 
    public static void main(String[] args) {

          Test test = new Test();

          test.getFile("test", "test.txt");

          test.getFile(null, "test1.txt");

          test.getFile("test2", "test2.txt");

    }
}

Outpt:

Data has been written in File test.txt

Some issue is coming while writing in file test1.txt

java.lang.NullPointerException

    at com.java.test.exception.Test.getFile(Test.java:16)

    at com.java.test.exception.Test.main(Test.java:33)

Data has been written in File test2.txt

User Defined Exception

Although Java has already provided a lot of exception classes then also it gives the privilege to create your own Exception class that is called User-defined Exception or custom exception class. Through Custom Exception we can have our own exception class and exception message.

User-defined exceptions are created specifically for the application, business logic, module, and workflow. It helps the application developer to debug and analyze the actual problem quickly.

How to create User defined exceptions

To create a User Defined Exception, you can create a class by extending the Exception class. This Custom exception class will not have any method while it will have overloaded constructor methods, Each constructor method will internally call its parent constructor.

Syntax: Class  <Exception class name> extends Exception

Custom Exception class example and implementation: In the given below example, we have created a CustomExceptin class named  “TestApplicationException”.  In Test class, we are using this custom class to throw the exception.

public class TestApplicationException extends Exception {
         TestApplicationException() {
            super();
         }
         TestApplicationException(String message) {
            super(message);
         }
         TestApplicationException (String message, Throwable exception) {
            super(message, exception);
         }
}
 
public class Test {
 
    public void getNumber(int arrayIndex) throws TestApplicationException {
          int[] testNum = { 1, 2, 3, 4 };
          if (arrayIndex > testNum.length - 1) {
                 throw new TestApplicationException("Array index is not valid");
          }
          System.out.println(testNum[arrayIndex]);
 
    }
 
    public static void main(String[] args) {
          try {
                 Test test = new Test();
                 test.getNumber(1);
                 test.getNumber(0);
                 test.getNumber(5);
                 test.getNumber(2);
                 test.getNumber(3);
          } catch (Exception e) {
                 e.printStackTrace();
          }
    }
}
Output:
2
1
com.java.test.exception.TestApplicationException: Array index is not valid
    at com.java.test.exception.Test.getNumber(Test.java:8)
    at com.java.test.exception.Test.main(Test.java:19)

Although there is no restriction to use any exception handling methods, it is recommended to use it carefully in your application. Because of Exception handling, it should not be like our main logic gone away, application readability, reliability, and maintainability are compromising, non-required events are filling in logs or application, or application performance is impacting. In the real world of programming, there are situations when we need to use nested try/catch block or multiple catch blocks, etc. But we recommend these should be implemented after proper analysis.

This article was written by Renu Singh

14+ Years of experience in various phases of the software development life cycle. Specialties: Java/J2EE, Struts, Hibernate, JSF, JSP, Servlets, AJAX, Oracle, Oracle Knowledge, SQL Server 2000, DB2, EJB3.0. Companies Worked For: 1) Tata Consultancy Services 2) Infogain 3) TS Infotech 4) Daffodil Software Ltd.

Leave a Reply

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