Beginners Programs :

Exception Handling In Java – Tutorial & Examples

What is Exception Handling In Java – When we work with a program we come up with different kinds of errors like syntactical errors, logical errors, runtime errors, etc. let us try to differentiate these errors with a simple program.

Example Program To Differentiate the Errors:

The above program will not cross the compilation stage because there is a semi-colon missing when declaring the variables a and b.

  • This is an error as per the syntax of Java language.
  • When our code fails to comply with the syntax of the language, the compiler will generate an error.
  • These kinds of errors are known as syntactical errors or compilation errors.
  • As the compiler catches the error and its location, we should make the required modifications and recompile the updated program.

Generally, these kinds of errors come to the people who do not have enough grip on the syntax of the language.

Then we have printed “sum is “+c with the first println() statement. We are trying to print the sum but in the previous statement, we have used multiplication symbol instead of the addition symbol.

These kinds of errors cannot be caught by the compiler. So the user will see some wrong result. This problem arose due to the wrong way of writing the logic. So these are known as logical errors.

For simplicity and easy understanding, we have given such a simple example (addition and multiplication). But in real time, a complex problem may be understood by the programmer in a wrong way and as per the understanding, the programmer will write the code.

At the testing stage, the mistake will be caught and as per the testing report, the programmer will have to make the required modifications to the program. Generally, this kind of problem occurs when we don’t have enough grip on the problem domain.

The third error we have seen in the above example is printing the quotient after the division. If the division is done with normal values, then we would get a normal result. But in our example, we are dividing a value (45) with 0.

In the subject of mathematics, there is no proper value defined for a division with 0 (it is said as infinite). So in Java also this operation cannot be performed.

Simple Flow Chart For Java Exception Handling

Java exception handling

As there is a limitation in the concept of mathematics, the same is reflected in Java, and the Java runtime system cannot proceed from that point. Hence it terminates the program (actually, the current thread) by printing some messages corresponding to the error.

  • These kinds of errors are known as runtime errors. But in a real-time environment, a program should not be terminated at any cost. It will be embarrassing to the user.
  • Not only that but also we (programmer) should know what problems the client/user has got while working. When we come to know the problem, we can find a solution, update the program, and give it to the user.
  • If the program does not terminate even such an error occur, that will be great. So programmer should have a provision not to terminate the program and handle that situation.

While handling, we can skip that part (which created the runtime error) and continue with the rest of the program.

Java provides a special mechanism to deal with these runtime errors. In Java parlance, the ‘runtime errors’ are known as ‘exceptions’. Handling (solving) the exception (errors) is known as ‘Exception Handling’.

For that it provides the keywords try, catch, throw, throws and finally.

Java Exception Handling

Let us see an example here that may raise an exception (runtime error). When the program is executed the program will be terminated abnormally.

Example:

As the program is trying to divide a value (4) by 0, an exception is raised and the program will be terminated. In the given program, there are 3 statements. The first statement will be executed normally and prints “Computer”.

The second statement will raise an exception and terminates the program. So the control will not come to the third statement.

Suppose, we want to see that the program will not be terminated at the second statement, but skips the problem creating a statement, and executes the third statement also.

For that, we can put the problem creating a statement in a try block. Generally, the statements that may raise an exception are placed in the ‘try’ block. If an exception is raised the control goes to the ‘catch’ block.

If no exception is raised, then the catch block is skipped. So if we write the above program in the following way, then the program will not be terminated abnormally.

Example:

Output:

In the above program, first “Computer” is printed normally. Then an exception is raised in the try block and control comes to the catch block. As there is no statement in the catch block, nothing will happen there. But the control comes out of the catch block and prints “Programming”.

If we don’t want to take any specific action when an exception is raised, then we can keep the catch block empty. If we want to perform any action (some alternative for the code in try block), then we can write some code in the catch block.

The Actual Work – Exception Handling

When a runtime error occurs, the system creates an object corresponding to the error and stores the information about the error in that object.

For example, when an attempt is made to divide by 0 an object of the class ArithmeticException is raised.

Similarly, when an attempt is made to access an element outside the array bounds (limits) then an object of the class ArrayIndexOutOfBoundsException is raised.

Suppose, when we try to access a character out of a String (using method like charAt()) then an object of the class StringIndexOutOfBoundsException is raised.

Once such an object is raised, the system throws that object to the catch block. If there is no catch block to receive the object, then the program will be terminated abnormally.

Otherwise, the object will be received by the catch block and the code we have specified there will be executed. That is why we have used an Exception reference at catch block (this is similar to a formal argument in a method).

The exception is a parent class for almost all the exceptions in Java. So the parent class reference will receive the HashCode of the created (and thrown) object. If we want to get information about the created object (and the error details) we can use that formal-argument-like variable.

Multiple Catch Blocks

The try block may raise different types of exceptions and we may want to take a different action for each of them. In that case, we can have multiple catch blocks associated with a try block.

Syntax:

Whatever the number of catch blocks we have for a try block, we should see a parent class catch block does not come before its child class catch block.

Otherwise, the parent class catch block handles the child class exception and the child class catch block becomes unreachable. The ‘unreachable’ code is not allowed in Java and such a situation will give a compilation error.

If we want to perform any activity irrespective of the exception raised ( it means the action will be performed whether an exception is raised or not) then we can put such code in the finally block. The finally block is a place just after the catch block.

Syntax: 

By default, the system throws an exception object when something goes wrong. It means the system has to create an object and throw (pass) it to catch block.

There may be some situations where it is acceptable to the system but not acceptable to the requirements of our program/project. In that case, we can create and throw the exception objects.

Creating an exception object is similar to the way we create any other object. To throw the created object, we use the keyword ‘throw’. This can be seen in the following example.

There are two types of exceptions

  1. Checked exceptions
  2. Unchecked exceptions

Checked Exceptions:

When there is a possibility for a checked exception to rising, the compiler will raise an error at compilation stage. So it is our responsibility to handle the checked exceptions without fail.

On the other hand, the compiler does not raise an error if there is a possibility for an unchecked exception. In fact, the compiler won’t check for them. This is why those exceptions are known as unchecked exceptions.

The exceptions for which the compiler would check are known as checked exceptions.

For all the exception classes, Throwable is the base class. The Throwable, Exception, all child classes of Exception except RuntimeException have checked exception classes.

The RuntimeException and all its child classes are unchecked exceptions. Similarly, Error and all its child classes are also unchecked only.

If there is any possibility for a checked exception to rising and we want the exception to be handled by another method that has called this method, then we should notify to the system that the exception is not being handled here so the caller should handle this.

If we notify so, then the compiler will not raise the error. To notify this, we use the clause ‘throws’. The ‘throws’ clause puts the responsibility of handling on the calling method.

If the calling method does not provide the exception handling, then the compiler raises an error at the calling method. In the following example, we can see the usage of ‘throws’.

Example:

In the above example, if we omit the ‘throws Exception’ at the fun() header then a compilation error will be raised. As Exception is a checked exception, throws clause is required.

In the above example, if we throw an unchecked exception (like ArithmeticException, NumberFormatException, etc) then we need not use the throws clause. The system can automatically throw the exception to the calling method.

If we want we can create our own exceptions also. Every exception class that we create (on our own) should be part of the exception hierarchy that starts at Throwable.

So we should make our class a child class to any of the existing exception classes.

Example: