Exception Handling in Java
Overview
Exception handling in Java is the process of responding to the occurrence of exceptions(Exceptions are unwanted conditions that disturb the program execution), it occurred.
Exceptional handling in Java is a very powerful mechanism as it helps to identify exceptional conditions and maintain the flow of the program as expected, by handling/avoiding the errors if occurred. In some cases, it is used to make the program user-friendly.
What is an Exception in Java?
An exception is an unwanted or unexpected event that occurs during the execution of the program, that disrupts the flow of the program.
For example, if a user is trying to divide an integer by 0 then it is an exception, as it is not possible mathematically.
There are various types of interruptions while executing any program like errors, exceptions, and bugs. These interruptions can be due to programming mistakes or due to system issues. Depending on the conditions they can be classified as errors and exceptions.
Java has classes that are used to handle built-in exceptions and provision to create user-defined exceptions. First, let's understand the meaning of the exception and error of the term.
1. Exception
- As mentioned earlier exceptions are unwanted conditions that disrupt the flow of the program.
- Exceptions usually occur due to the code and can be recovered.
- Exceptions can be of both checked(exceptions that are checked by the compiler) and unchecked(exceptions that cannot be checked by the compiler) type.
- They can occur at both run time and compile time.
- In Java, exceptions belong to java.lang.Exception class.
2. Error
- An error is also an unwanted condition but it is caused due to lack of resources and indicates a serious problem.
- Errors are irrecoverable, they cannot be handled by the programmers.
- Errors are of unchecked type only.
- They can occur only at run time.
- In java, errors belong to java.lang.error class.
- Eg: OutOfMemmoryError.
What is Exception Handling in java?
Exception handling in java is a mechanism to handle unwanted interruptions like exceptions and continue with the normal flow of the program.
Java uses try-catch blocks and other keywords like finally, throw, and throws to handle exceptions. JVM(Java Virtual Machine) by default handles exceptions, when an exception is raised it will halt the execution of the program and throw the occurred exception.
Why Handle Java Exception?
We handle exceptions in java to make sure the program executes properly without any halt, which occurs when an exception is raised. These exceptions are runtime as well as compile-time. They may be minor exceptions but can cause a problem in executions of the program, hence it becomes necessary to handle java exceptions. If java exceptions are not handled, programs may crash and execution is halted in between.
For example, if there is a program with some lines of code and an exception occurs a mid-way after executing certain lines of code, in this case, the execution terminates abruptly.
But if the programmer handles the exceptions explicitly, all the statements of code are executed properly and the flow of the program is maintained.
Let's see a code for the same.
Output:
In the above code, the first three lines in the main method are executed properly. At the 4th line, an integer is divided by 0, which is not possible and an exception is raised by JVM(Java Virtual Machine). In this case, the exception is not handled by the programmer which will halt the program in between by throwing the exception, and the rest of the lines of code won't be executed.
How does JVM handles an Exception?
Java exceptions raised during the program execution are nothing but objects of the respective exception class in the hierarchy shown above. The exceptions have a naming and inheritance hierarchy to the main exception class in java i.e. Throwable class. All java exception objects support the toString() method, which returns the full name of the exception class as an output to the command prompt, which helps to understand the exceptional condition.
Whenever an exception has occurred inside a method, the method creates an exception object and hands it over to JVM.
This object contains the name and description of the exception and the current state of the program where the exception has occurred. This is called the process of object creation and handing it over to JVM is known as throwing an Exception. This object is an exception that is further handled by JVM.
When an exception is raised there is an ordered list of the methods that had been called by JVM to get the method where the exception has occurred this list is called Call Stack.
JVM searches through this call stack to get the proper code to handle the occurred exception, this code block is known as an Exception handler. When an appropriate handler is found JVM handles the exception according to the code in the handler and shows the state of the program.
Here is a sample program:
Output:
But if it is not able to find the handler JVM uses the default exception handler, which is part of the run-time system. But this default exception handler throws an exception and terminates the program abnormally.
Hierarchy of Java Exception Classes
As java is an object-oriented language every class extends the Object class. All exceptions and errors are subclasses of class Throwable. Throwable is the base/superclass of exception handling hierarchy in java. This class is further extended in different classes like exception, error, and so on.
Types of Exceptions Handling in Java
1. Checked Exceptions
- Checked exceptions are those exceptions that are checked at compile time by the compiler.
- The program will not compile if they are not handled.
- These exceptions are child classes of the Exception class.
- IOException, ClassNotFoundException, InvocationTargetException, and SQL Exception are a few of the checked exceptions in Java.
2. Unchecked Exceptions
- Unchecked exceptions are those exceptions that are checked at run time by JVM, as the compiler cannot check unchecked exceptions,
- The programs with unchecked exceptions get compiled successfully but they give runtime errors if not handled.
- These are child classes of Runtime Exception Class.
- ArithmeticException, NullPointerException, NumberFormatException, IndexOutOfBoundException are a few of the unchecked exceptions in Java.
Difference Between Checked and Unchecked Exceptions
Checked Exception | Unchecked Exception |
---|---|
Occur at compile time. | Occur at runtime. |
The compiler checks for checked exceptions. | The compiler does not check for unchecked exceptions. |
If checked exceptions are not handled we get a compile-time error. | If unchecked exceptions are not handled we get a run time error. |
Can be handled at compile time. | Can not be caught/handled at runtime. |
They are direct subclasses of exception class but do not inherit Runtime Exception Class. | They are subclasses of the Runtime Exception class. |
Eg: IOException, ClassNotFoundException, SQLException are common checked exceptions. | Eg: ArithmeticException, NullPointerException, NumberFormatException, StringIndexOutOfBoundException, ArrayIndexOutOfBound Exception are common unchecked exceptions. |
How does a Programmer Handles an Exception?
Customized exception handling in java is achieved using five keywords: try, catch, throw, throws, and finally. Here is how these keywords work in short.
- Try block contains the program statements that may raise an exception.
- Catch block catches the raised exception and handles it.
- Throw keyword is used to explicitly throw an exception.
- Throws keyword is used to declare an exception.
- Finally block contains statements that must be executed after the try block.
Example of Exception Handling in Java
Output:
Java Exception Keywords and Examples
1. try block
- try block is used to execute doubtful statements which can throw exceptions.
- try block can have multiple statements.
- Try block cannot be executed on itself, there has to be at least one catch block or finally block with a try block.
- When any exception occurs in a try block, the appropriate exception object will be redirected to the catch block, this catch block will handle the exception according to statements in it and continue the further execution.
- The control of execution goes from the try block to the catch block once an exception occurs.
Syntax
2. catch block
- catch block is used to give a solution or alternative for an exception.
- catch block is used to handle the exception by declaring the type of exception within the parameter.
- The declared exception must be the parent class exception or the generated exception type in the exception class hierarchy or a user-defined exception.
- You can use multiple catch blocks with a single try block.
Syntax
Programming examples using try-catch blocks
1. try-catch block
Let's see a simple example of exception handling in java using a try-catch block.
Output:
In this program, the user has declared an array myNumbers in the try block, which has some numbers stored in it. And the user is trying to access an element of the array that is stored at the 10th position.
But array has only 6 elements and the highest address position is 5. By doing this user is trying to access an element that is not present in the array, this will raise an exception, and the catch block will get executed.
2. Multiple Catch Blocks
Java can have a single try block and multiple catch blocks and a relevant catch block gets executed.
Example 1:
Here we are giving doubtful statements in a try block and using multiple catch blocks to handle the exception that will occur according to the statement.
Output:
In this example, the try block has doubtful statements that are trying to divide an integer by 0 and 3 catch blocks which have mentioned the exceptions that can handle. After execution of the try block, the Arithmetic Exception is raised and JVM starts to search for the catch block to handle the same.
JVM will find the first catch block that can handle the raised exception, and control will be passed to that catch block. After the exception is handled the flow of the program comes out from try-catch block and it will execute the rest of the code.
Example 2:
Output:
In this example, try block has doubtful statements that are trying to access elements that are not present in an array and 3 catch blocks that have mentioned the exceptions that can handle. After execution of try block, ArrayIndexOutOfBounds Exception is raised and JVM starts to search for the catch block to handle the same.
JVM will find the second catch block that can handle the raised exception, and control will be passed to that catch block. After the exception is handled the flow of the program comes out from try-catch block and it will execute rest of the code.
3. Nested Try Catch
Here we have deep (two-level) nesting which means we have a try-catch block inside a nested try block. To make you understand better I have given the names to each try block in comments like try-block2, try-block3, etc.
Output:
As you can see that the ArrayIndexOutOfBoundsException occurred in the grandchild try-block3. Since try-block3 is not handling this exception, the control then gets transferred to the parent try-block2 and looked for the catch handlers in try-block2.
Since the try-block2 is also not handling that exception, the control gets transferred to the main (grandparent) try-block where it found the appropriate catch block for an exception. We can use the finally block after the main try-catch block if required.
4. finally block
- finally block is associated with a try, catch block.
- It is executed every time irrespective of exception is thrown or not.
- finally block is used to execute important statements such as closing statement, release the resources, and release memory also.
- finally block can be used with try block with or without catch block.
Syntax
Example:
Output:
Here, after the execution of try and catch blocks, finally block gets executed. finally block gets executed even if the catch block is not executed.
5. Java Final Vs Finally Vs Finalize
Java has 3 different keywords used in exception handling final, finally, and finalize. These are different keywords with completely different functionality.
final | finally | finalize |
---|---|---|
final is the keyword and access modifier | finally block is used in java Exception Handling to execute the important code after try-catch blocks. | finalize is the method in Java. |
final access modifier is used to apply restrictions on the variables, methods, classes. | finally block executes whether an exception occurs or not. It is used to close resources. | finalize() method is used to perform clean-up processing just before an object is a garbage collected. |
It isused with variables, methods, and classes. | It is with the try-catch block in exception handling. | Used with objects. |
Once declared, the final variable becomes constant and can't be modified. | finally block cleans up all the resources used in the try block. | finalize method performs the cleaning with respect to object before its destruction. |
final is executed only when we call it. | finally block executes as soon as the execution of try-catch block is completed without depending on the exception. | finalize method is executed just before the object is destroyed. |
6. throw keyword
- throw keyword in java is used to throw an exception explicitly.
- We can throw checked as well as unchecked exceptions (compile-time and runtime) using it.
- We specify the class of exception object which is to be thrown. The exception has some error message with it that provides the error description.
- We can also define our own set of conditions for which we can throw an exception explicitly using the throw keyword.
- The flow of execution of the program stops immediately after the throw statement is executed and the nearest try block is checked to see if it has a catch statement that matches the type of exception.
- It tries to find all the catch blocks until it finds the respective handler, else it transfers the control to the default handler which will halt the program.
Syntax
Example: Here is an example to check the age of the user and raise an exception explicitly using the throw keyword, if the user doesn't fit in the criteria. Also, a customized message is given to the user which helps in understanding the exception.
Output:
Here throw keyword is used to inform the user that he/she does not fit in the required criteria. If age is less than 18 then the throw keyword explicitly throws an arithmetic exception. When chekAge method is given input 15 an exception is raised and if block will get executed. In case the input is greater than 15 it will execute else block.
7. throws keyword
- throws keyword in java is used in the signature of the method to indicate that this method might throw one of the exceptions from java exception class hierarchy.
- throws keyword is used only for checked exceptions like IOException as using it with unchecked exceptions is meaningless(Unchecked exceptions can be avoided by correcting the programming mistakes.)
- throws keyword can be used to declare an exception.
Example:
Let's see the same example of checking age using the throws keyword. Instead of throwing exceptions explicitly, we will declare an exception in checkAge method signature using the throws keyword.
Output:
Here the exception is declared in the method itself using the throws keyword. If age is less than 18 then the throw keyword will raise an exception declared by throws keyword. When chekAge method is given input 15 an exception is raised and if block will get executed. In case input is greater than 15 it will execute else block.
8. Throw Vs Throws
Throw | Throws |
---|---|
Java throw keyword is used to throw an exception explicitly in the program, inside any block of code | Java throws keyword is used in method or function signature to declare an exception that the method may throw while execution of code. |
throw keyword can be used to throw both checked and unchecked exceptions. | throws keyword can be used only with checked exceptions. |
throw is used within the method. | throws is used within the method signature. |
Syntax: throw new exception_class("error message"); | Syntax: void method() throws ArithmeticException |
We can throw only one exception at a time. | We can declare multiple exceptions using the throws keyword that the method can throw. |
9. Custom Exceptions in Java
- Custom exceptions are user-defined exceptions.
- We can create exceptions as per the requirement by extending the Exception class that belongs to java.lang package.
- These are the exceptions related to business logic where a developer wants the user to give input in the required format and if user fails to do so an exception is raised and user gets instructions of what the problem is and how it can be resolved. It is useful for the application users or the developer to understand the exact problem.
- Example: In case a user wants to set Age limit we can use custom exceptions and give the required comment as an output.
Output:
As we can see above, InvalidProductException is the customized exceptions created by extending the exception class.
And this exception is used in Check method signature using the throws keyword. When an argument passed to the method is less than 50, an exception is raised, and the catch block gets executed. Use this Online Java Compiler to compile your code.
Common Scenarios of Java Exceptions
1. ArithmeticException
Arithmetic exceptions is raised by JVM when we try to perform any arithmetic operation which is not possible in mathematics. One of the most common arithmetic exception that occurs is when we divide any number with zero.
2. NullPointerException
NullPointerException occurs when a user tries to access variable that stores null values. For example, if a variable stores null value and the user tries to perform any operation on that variable throws NullPointerException.
3. NumberFormatException
In java, variables have data types and certain operations are compatible with specific data types. Some functions are to be performed on numeric values, but if a variable with an incompatible data type like string is given as an input, it results in NumberFormatException.
For example, trying to convert string into digit.
4. ArrayIndexOutOfBoundsException
While accessing an array if we access an element that is present in an array it will execute properly without throwing any exceptions, but accessing an index that is not present throws ArrayIndexOutOfBoundsException.
5. StringIndexOutOfBoundsException
It is the same as ArrayIndexOutOfBoundsException but it is for strings instead of arrays. Here if the length of a string is less than what we are trying to access then we get StringIndexOutOfBoundsException.
Exception Handling in Java: Best Practices
- Always catch only those exceptions that can be handled.
- Null values should not be returned in catch block rather than handling an exception, it consumes the exception and the error fails permanently and programs crashes.
- Don't get the exception class instead catch particular subclasses.
- Never throw an exception from the finally block, because even if any exception is not raised in the try block, finally block will throw the exception, after execution of try-catch blocks.
- Use finally blocks instead of catch blocks if you are not going to handle the exception.
- Always use the finally block to close the used resources.
Advantages of Exception Handling in Java
- Program execution continues if an exception is raised and handled, it does not terminate the code being executed abruptly.
- With exception handling it is easy to identify errors that occurred while execution.
- The exceptions thrown in a Java program are objects of a class. Since the Throwable class overrides the toString() method, you can obtain a description of an exception in the form of a string.
- Java provides several super classes and subclasses that group exceptions based on their type it is easy to differentiate and group exceptions.
Important Points to Remember
- try block should have at least one catch or one finally block for execution.
- If there is the possibility of multiple exceptions being raised multiple and respective catch blocks should be used.
- At a time only one exception occurs and at a time only one catch block is executed.
- All catch blocks must be ordered from most specific to most general sequentially.
- Most important use of finally block is to close the used data resources.
- throw keyword is mainly used to throw custom exceptions.
- Custom exceptions are used to make the program user-friendly.
- Final, finally, and finalize are three different keywords with completely different functionalities in java.
Conclusion
- Exception handling in java is a way to handle unwanted conditions while programming.
- Java uses exception handling very efficiently, basically with five keywords try, catch, finally, throw, and throws.
- Java provides provision to declare and use custom exceptions by extending the Exception class.
- Exception handling makes the program efficient in terms of handling errors/exceptions and user-friendly, as user can understand the exceptions easily.
- With the use of this mechanism error handling becomes easy as errors are described.