Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

An Overview of Java Exception Handling

In this article we will learn about the basic concepts of exception handling and its implementation in Java programming.

Why we need Exception handling and what does it mean? So let’s discuss about it. In general terms we can say exception are like errors.

“To produce quality code that does not fail unexpectedly, we must design or implement error handling into our code or program.” Exception is an error event that can happen during the execution of a program and disrupts its normal flow.Unhandled errors may create problems in results or can create a situation of abnormal program termination. Java provides a robust and object oriented way to handle exception scenarios, known as Java Exception Handling.

Process of exception handling:

a) Throwing the exception: As we are aware that Java adheres to the concepts of oops , whenever an error occurs while executing a statement in program , it creates an exception object and then the normal flow of the Java program halts and Java runtime (JRE) tries to find someone that can handle the raised exception. The exception object contains a lot of debugging information such as method hierarchy, line number where the exception occurred, type of exception etc. When the exception occurs in a method, the process of creating the exception object and handing it over to runtime environment is called “throwing the exception”.

b) Catching the exception: Once Java runtime receives the exception object, it tries to find the handler for the exception. Exception Handler is the block of code that can process the exception object. If the appropriate exception handler is found, the exception object is passed to the handler to process it. The handler is said to be “catching the exception”. If there are no appropriate exception handler found then program terminates printing information about the exception.

Keywords in Exception Hanlding


  1. throw: If any exception occurs in a program, an exception object is created instantly and JRE is instructed to handle this exception object. throw keyword is used to throw exception to the runtime to handle it.
  2. throws: When we are throwing any exception in a method and not handling it, then we need to use throws keyword in method signature to let calling program know the exceptions that might be thrown by the method.
  3. try-catch: We use try-catch block for exception handling in our code. try is the start of the block and catch is at the end of try block to handle the exceptions. We can have multiple catch blocks with a try and try-catch block can be nested also. catch block requires a parameter that should be of type Exception.
  4. Finally: finally block is optional and can be used only with try-catch block. Since an exception halts the process of execution, we might have some resources open that will not get closed, so we can use finally block. finally block gets executed always, whether exception occurred or not.

Types of Exception

There are mainly 3 types of exceptions:

  1. Checked Exception: The classes that extend Throwable class except RuntimeException and Error are known as checked exceptions e.g.IOException, SQLException etc. Checked exceptions are checked at compile-time.
  2. Unchecked Exception: The classes that extend RuntimeException are known as unchecked exceptions e.g. ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException etc. Unchecked exceptions are not checked at compile-time rather they are checked at runtime.
  3. Error: Error is irrecoverable e.g. OutOfMemoryError, VirtualMachineError, AssertionError etc.

Common scenarios of Exception Handling where exceptions may occur:

  1. int a=50/0;//ArithmeticException  
  2. String s=null;   System.out.println(s.length());//NullPointerException  
  3. String s="abc";  
     a. int i=Integer.parseInt(s);//NumberFormatException 
  4. int a[]=new int[5]; 
      a[10]=50; //ArrayIndexOutOfBoundsException  

Listing 1: Simple example of Try-Catch Block

  Class TryCatchCheck
  {
    public static void main(String args[])
    {  
     try
    {  
        int data=50/0;      
     }
    catch(ArithmeticException e)
    {
        System.out.println(e);
    }  
    System.out.println("rest of the code...");  
   }  
  } 

Output : Exception in thread main Java.lang.ArithmeticException:/ by zero

rest of the code...

Explanation Listing 1: Here we use try-catch block to catch the exception generated in statement (50/0).

Listing 2: Multiple Try-Catch Block

  Class TryCatchMultipleCheck
  {
  public static void main(String args[])
  {  
    try
  {  
    int a[]=new int[5];  
    a[5]=30/0;  
  }  
  catch(ArithmeticException e)
  {              
    System.out.println("task1 is completed");    
  }  
  catch(ArrayIndexOutOfBoundsException e)
  {
    System.out.println("task 2 completed");
  }  
  catch(Exception e)
  {
    System.out.println("common task completed");
  }  
  System.out.println("rest of the code...");  
  }  
 }  

Output : task 1 is completed

rest of the code...

Explanation Listing 2: Here multiple catch blocks are associated with a single try block and the appropriate catch block is called after the program execution.

Only one Exception occurs at a time and only one catch block is executed at a time.

All catch blocks must be ordered from most specific to most general i.e. catch for ArithmeticException must come before catch for Exception.

Listing 3 : finally Block this finally block must be followed by try or catch block. The JVM executes finally blocks before the termination of the program.

  class BlockFinal
  {  
    public static void main(String args[])
  {  
    try{  
           int data=25/5;  
           System.out.println(data);  
    }  
           catch(NullPointerException e)
   {
           System.out.println(e);
   }     
   finally
  {
     System.out.println("finally block is always executed");
  }  
     
  System.out.println("rest of the code...");  
 }  
}  
  

Output : finally block is always executed

rest of the code...

Explanation Listing 3: As output says finally statement will always be executed whether there is an exception in program or not.

Rule: For each try block there can be zero or more catch blocks, but only one finally block.

Listing 4: throw keyword

  class ThrowException
  {  
   static void validate(int age)
   {  
       if (age<18)  
                 throw new ArithmeticException("not valid");  
       else  
                  System.out.println("welcome to vote");  
     }  
       
      public static void main(String args[])
      {  
        validate(13);  
        System.out.println("rest of the code...");  
      }  
  }  
  

Output: Exception in thread main Java.lang.ArithmeticException: not valid

Explanation Listing 4: If the age is less than 18, we are throwing the ArithmeticException otherwise print a message welcome to vote.

Note that Java Exception handling is a framework that is used to handle runtime errors only, compile time errors.

Useful Exception Methods

Exception (and all of its subclasses) doesn’t provide any specific methods. The methods are defined in the base class Throwable. The exception classes are created to specify different kind of exception scenarios so that we can easily identify the root cause and handle the exception according to its type. Throwable class implements Serializable interface for interoperability.

Some of the useful methods of Throwable class are:

  1. public String getMessage() – This method returns the message String of Throwable and the message can be provided while creating the exception through it’s constructor.
  2. public String getLocalizedMessage() – This method is provided so that subclasses can override it to provide locale specific message to the calling program. Throwable class implementation of this method simply use getMessage() method to return the exception message.
  3. public synchronized Throwable getCause() – This method returns the cause of the exception or null if the cause is unknown.
  4. public String toString() – This method returns the information about Throwable in String format.The returned String contains the name of Throwable class and localized message.
  5. public void printStackTrace() – This method prints the stack trace information to the standard error stream.This method is overloaded and we can pass PrintStream or PrintWriter as an argument to write the stack trace information to the file or stream.

There are some best practices you must consider and follow in exception handling:

  1. Catch Late:Since Java insists on either handling the checked exception or on declaring it in method signature, sometimes developers tend to catch the exception and log the error. But this practice is harmful because the calling program doesn’t get any notification of the exception. We should catch an exception only when we can handle it appropriately. For example, in the above method, I am throwing exception back to the caller method to handle it. The same method could be used by other applications that might want to process the exception in a different manner. While implementing any feature, we should always throw exceptions back to the caller and let them decide how to handle it.
  2. Declare the specific checked exceptions that your method can throw
    public void foo() throws Exception { //Incorrect way
    }
    Always avoid doing this as in above code sample. It simply ignores the whole purpose of having a checked exception. Declare the specific checked exceptions that your method can throw. If there are just too many such checked exceptions, you should probably wrap them in your own exception and add information to the exception message.

    The correct way of doing this is:

    public void foo() throws SpecificException1, 
    SpecificException2 { //Correct way}
  3. Naming Conventions and Packaging:When you create your custom exception, make sure it ends with Exception so that it will be clear from the name itself that it’s an exception. Also make sure to package them like it’s done in the JDK. For example, IOException is the base exception for all IO operations.
  4. Never catch Throwable class:Well,this step is more serious than the previous one. Because Java errors are also subclasses of the Throwable. Errors are irreversible conditions that can not be handled by JVM itself. And for some JVM implementations, JVM might not actually even invoke your catch clause on an Error.
  5. Always correctly wrap the exceptions in custom exceptions so that stack trace is not lost
    catch (NoSuchMethodException e) {
    throw new MyServiceException("Some information: " + e.getMessage()); //Incorrect way
    }

    This destroys the stack trace of the original exception, and is always wrong. The correct way of doing this is:

    catch (NoSuchMethodException e) {
    throw new MyServiceException("Some information: " , e); //Correct way
    }
  6. Either log the exception or throw it but never do the both
    catch (NoSuchMethodException e) {
    LOGGER.error("Some information", e);
    throw e;
    }

    As in above example code, logging and throwing will result in multiple log messages in log files, for a single problem in the code, and makes life difficult for the engineer who is trying to dig through the logs.

  7. Never throw any exception from finally block
    try {
    someMethod(); //Throws exceptionOne
    } finally {
    cleanUp(); //If finally also threw any exception the exceptionOne 
      //will be lost forever
    }

    This is fine, as long as cleanUp() can never throw any exception. In the above example, if someMethod() throws an exception, and in the finally block also, cleanUp() throws an exception, that second exception will come out of the method and the original (first) exception (correct reason) will be lost forever. If the code that you call in a finally block can possibly throw an exception, make sure that you either handle it, or log it. Never let it come out of the finally block.

  8. Always catch only those exceptions that you can actually handle
    catch (NoSuchMethodException e) {
    throw e; //Avoid this as it doesn't help anything
    }
    Well, this is the most important concept. Don’t catch any exception just for the sake of catching it. Catch any exception only if you want to handle it or, you want to provide additional contextual information in that exception. If you can’t handle it in the catch block, then just don’t catch it, only re-throw it.
  9. Don’t use printStackTrace() statement or similar methods: Never leave printStackTrace() after finishing your code. Chances are one of your fellow colleague will get one of those stack traces eventually, and have exactly zero knowledge as to what to do with it because it will not have any contextual information appended to it.
  10. Use finally blocks instead of catch blocks if you are not going to handle exception
    try {
    someMethod(); //Method 2
    } finally {
    cleanUp(); //do cleanup here
    }
    This is also a good practice. If inside your method you are accessing some method 2, and method 2 throw some exception which you do not want to handle in method 1, but still want some cleanup in case an exception occurs, then do this cleanup in the finally block. Do not use catch block.
  11. Remember “Throw early catch late” principle:This is probably the most famous principle about Exception handling. It basically says that you should throw an exception as soon as you can, and catch it late as much as possible. You should wait until you have all the information to handle it properly. This principle implicitly says that you will be more likely to throw it in the low-level methods, where you will be checking if single values are null or not appropriate. And you will be making the exception climb the stack trace for quite several levels until you reach a sufficient level of abstraction to be able to handle the problem.
  12. Always clean up after handling the exception:If you are using resources like database connections or network connections, make sure you clean them up. If the API you are invoking uses only unchecked exceptions, you should still clean up resources after use, with try – finally blocks. Inside the try block access the resource and inside the finally block close the resource. Even if any exception occur in accessing the resource, then the resource will also be closed gracefully.
  13. Throw only relevant exception from a method: Relevancy is important to keep application clean. If amethod tries to read a file and throws NullPointerException, then it will not give any relevant information to the user. Instead it will be better if such exception is wrapped inside a custom exception e.g. NoSuchFileFoundException. That way it will be more useful for users of that method.
  14. Never use exceptions for flow control in your program:We have read it many times but sometimes we keep seeing code in our project where a developer tries to use exceptions for application logic. Never do that. It makes code hard to read, understand and ugly.
  15. Validate user input to catch adverse conditions very early in request processing:Always validate user input in very early stages, . It will help you to minimize the exception handling code in your core application logic. It also helps you in making application consistent if there is some error in user input. For example: In a user registration application, you are following the logic below:
    1) Validate User
    2) Insert User
    3) Validate address
    4) Insert address
    5) If there is a problem, then rollback everything
    This is a very incorrect approach. It can leave your database in an inconsistent state in various scenarios. Rather, validate everything in first place and then take the user data in DAO layer and make DB updates. Correct approach is:
    1) Validate User
    2) Validate address
    3) Insert User
    4) Insert address
    5) If there is a problem, then rollback everything
  16. Pass all relevant information to exceptions to make them informative as much as possible:This is also very important to make exception messages and stack traces useful and informative. What is the use of a log, if you are not able to determine anything out of it?

Conclusion

In this tutorial we learned the basic concepts of exception handling in Java, and got the idea of how to handle exceptions in different ways.



Have experience over java, c++ c#, web-development, android development.

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login