Java Exceptions - A complete guide
An exception in java is a situation that indicates the occurrence of some unexpected condition. This unexpected condition can be anything like - the requested resource or file is not found, the connection to a network is failed or the array index is out of bounds, etc. To handle such unexpected conditions, Java provides a mechanism called exception handling. Java exception handling is built around a paradigm called throw-and-catch. Throwing an exception signifies that an unexpected condition has occurred. Whereas to catch an exception signifies the application of appropriate steps and actions to handle or deal with the exception. In java, this entire throw-and-catch principle is embedded in try-catch-finally blocks.
Stack trace in Java
A java program can have multiple threads that are executing. Each thread has its own runtime stack.
This runtime stack handles the execution of methods.
Each element on the stack corresponds to a method call and every call results in a new activation record being pushed
on the stack.
This activation record contains all the pertinent information of the local variables (belonging to the method).
Now the method having an activation record on top of the stack is the one currently executing. Once this method finishes
its execution, its activation record pops out of the stack and the method with activation record uncovered on the top of the
stack is now executing. The currently executing method on the stack is said to be active until it finishes its execution.
These active methods on a runtime stack are called stack trace of a thread.
Consider the below program where 3 methods are there. The unexpected condition
occur during the execution of method 3 therefore its activation record pops out
of the stack abruptly because there is no exception handling implemented in method 3.
Therefore the exception that occurred at method 3 will now be propagated to method -2 whose activation record now is at the top of the stack but since this method also has no exception handling implemented,
therefore this method also pops out of the stack abruptly.
Now finally the exception will propagate to the main() method.
Since the main() method also has no exception handling code written to deal with the unexpected condition, therefore
the main() method also stops abruptly and the exception will be dealt with by the main thread's default exception handler.
This default exception handler will just print the name of the exception with a detailed
explanatory message.
An uncaught exception kills the thread in which the exception occurred.
What are the types of exceptions in java? | Checked and unchecked exceptions
Before understanding the checked and unchecked exceptions, first, understand the categorization and hierarchy of 'java.lang.Throwable' class. In java, all exceptions are objects. All exceptions are derived from the 'java.lang.Throwable' class. Two main subclasses of Throwable are 'Exception' and 'Error' that categories throwables.
Exception class- Exception class represents all types of exceptions that may occur during program execution.
Error class- Error class is defined in java.lang.Error class.
Its subclass AssertionError is used by the java assertion facility.
Other subclasses of the 'java.lang.Error' class define exceptions that indicate class linkage, thread, virtual machine-related
problem and can never be caught explicitly.
Checked and unchecked exceptions
Checked exceptions are those that are compulsorily need to be dealt with explicitly by the method.
The compiler makes sure that if a method can throw a checked exception, then the method must explicitly deal with it
either by using try-catch statements or bypassing the exception to its caller using the 'throws' clause.
If a checked exception is not handled by either of the above steps, then the compiler won't compile the code
and compilation error will occur during code compilation.
Unchecked exceptions are those that are not necessarily needed to be dealt with explicitly by the method.
Exceptions defined by Error and RuntimeException classes and their subclasses are known as unchecked exceptions.
These usually occur at runtime
How to define new exceptions?
Apart from using the existing Exception classes, a user can define a new exception to provide further
categorization of exceptional conditions.
To create a new exception, extend the Exception class or one of its checked subclasses to make it a checked one.
As all the exceptions in java are objects i.e. they are defined by classes, therefore the new exception can also declare
fields and methods thus providing more meaning and info to their cause and remedy when they are thrown and caught.
The below code snippet shows a new exception is defined by extending the Exception class.
This new exception will be thrown if certain conditions are met. Here in this example,
if a division of a number by another number resulting in the number itself then this exception will be thrown.
Also, this exception is caught in the appropriate catch block defined for catching this exception.
How to handle the exceptions? | Exception handling
Java provides a mechanism to handle the exception in the form of try, catch, finally construct.
An exception (any unconditional situation) that occurred in the code written inside the try block,
will be handled in the catch block. The code after the point where the exception occurred in the try block will be skipped
and the catch block will execute.
'finally' block will always execute no matter what was the cause of exit from the try block or whether
the catch block executed or not.
A try block can have multiple catch blocks, but only one 'finally' block.
Also, at least one of the blocks (either catch or finally) is necessary following the try block.
A 'try', 'catch', and 'finally' construct can also be nested in any other try, catch, or finally block.
If code written in the try block executes successfully, without any exception, then the catch block
gets skipped, and the 'finally' block will execute.
A catch block must accept only one argument that represents the type of exception this catch block will handle.
Difference between 'throw' and 'throws'?
'throw' keyword is used to throw an exception explicitly. A program can be made to throw an exception
explicitly by using the 'throw' keyword.
The syntax of throwing an exception is:
throw new ArithmeticException("int division by zero");
Whereas to propagate the exception to the caller of the method we use the 'throws' keyword.
The syntax for using the 'throws' keyword is
public void func1() throws InterruptedException{
}
Here, the 'throws' keyword signifies that this method -(func1) may cause InterruptedException therefore whosoever
calls this method must use try-catch construct for the method call
or propagate the exception to its caller by the 'throws' keyword.