☰
An exception is an exceptional event that can happen during the execution of a program and disrupts its normal flow. An Exception can be anything which interrupts the normal flow of the program. When an Exception occurs the normal flow of the program is disrupted and the program terminates abnormally, which is not recommended. Therefore these exceptions must be handled.
Java provides a robust and object oriented way to handle exception scenarios, known as Java Exception Handling. It is one of the powerful mechanism to handle the runtime errors so that normal flow of the application can be maintained.
This article digs deeper into exception handling in Java. It covers various do's and dont's of Java exception handling.
An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions. A Java Exception is an object that describes the exception that occurs. When an error occurs within a method, the method creates an object and hands it off to the runtime system. The object is called an exception object. The exception object contains a lot of debugging information such as method hierarchy, line number where the exception occurred, type of exception etc. Creating an exception object and handing it to the runtime system is called throwing an exception.
Once 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. Runtime starts the search in the method where error occurred, if no appropriate handler found, then move to the caller method and so on. The list of methods is known as the call stack.
The runtime system searches the call stack for a method that contains a block of code that can handle the exception. This block of code is called an exception handler. The search begins with the method in which the error occurred and proceeds through the call stack in the reverse order in which the methods were called. When an appropriate handler is found, the runtime system passes the exception object to the handler to process it. An exception handler is considered appropriate if the type of the exception object thrown matches the type that can be handled by the handler.
The exception handler chosen is said to be "catching the exception". If the runtime system exhaustively searches all the methods on the call stack without finding an appropriate exception handler, the runtime system terminates and, consequently, the program terminates printing information about the exception.
Exception can occur at runtime (known as runtime exceptions) as well as at compile-time (known Compile-time exceptions). Exception can occur from different kind of situations such as JVM has run out of memory, invalid data entered by user, missing file, network connection failure, database server down, hardware failure etc. So exceptions are caused by user error, by programmer error, or by physical resources that have failed in some manner. Based on these we can categorize Exceptions into three types:
These are exceptional conditions that a well-written application should anticipate and recover from. That is the exceptions that can be predicted by the programmer. Example : File that need to be opened is not found. These type of exceptions must be checked at compile time.
So a checked exception is an exception that occurs at the compile time, and hence are also called as compile time exceptions. These exceptions cannot be ignored at the time of compilation. If these exceptions are not handled in the program, it will give compilation error.
Examples of Checked Exceptions :
These are exceptional conditions that are external to the application, and that the application usually cannot anticipate or recover from. Unchecked exception are ignored at compile time. Unchecked Exceptions are also known as Runtime Exceptions as the compiler do not check whether the programmer has handled them or not. But it’s the duty of the programmer to handle these exceptions. These exceptions need not be included in any method’s throws list because compiler does not check to see if a method handles or throws these exceptions.
For example, if you have declared an array of size 10 in your program, and trying to access the 13th element of the array then an ArrayIndexOutOfBoundsExceptionexception occurs.
Examples of Unchecked Exceptions :
These are exceptional conditions that are internal to the application, and that the application usually cannot anticipate or recover from. These usually indicate programming bugs, such as logic errors or improper use of an API. Errors are typically ignored in code because you can rarely do anything about an error.
For example, a stack overflow error is not possible handle in code.
Note:Errors and runtime exceptions are collectively known as unchecked exceptions.
Exceptions in Java are hierarchical and inheritance is used to categorize different types of exceptions. All exception classes are subtypes of the java.lang.Exception class. The exception class is a subclass of the Throwable class. So Throwable class is at the top of exception class hierarchy and it has two child objects – Error and Exception. Exceptions are further divided into different checked exceptions and runtime exception.
The advantage of exception hierarchies is that if you decide to catch a certain exception in the hierarchy, then you will automatically also catch all subclasses of that exception too. In other words, you will catch all exceptions from that certain exception and down the hierarchy. For example, if you catch IOException which is the superclass of FileNotFoundException, you will also catch FileNotFoundException.
Exceptions provide the means to separate the details of what to do when something out of the ordinary happens from the main logic of a program. In traditional programming, error detection, reporting, and handling often lead to confusing spaghetti code.
Advantage of exceptions is the ability to propagate error reporting up the call stack of methods. Java runtime searches backward through the call stack to find any methods that are interested in handling a particular exception. A method can duck any exceptions thrown within it, thereby allowing a method farther up the call stack to catch it. Hence, only the methods that care about errors have to worry about detecting errors.
A method can catch an exception based on its group or general type by specifying any of the exception's superclasses in the catch statement. For example, to catch all I/O exceptions, regardless of their specific type, an exception handler specifies an IOException argument.
catch (IOException e) {
...
}
This handler will be able to catch all I/O exceptions, including FileNotFoundException, EOFException, and so on.