What are exceptions in JAVA?
In JAVA, Exception is an Object that describes an exceptional condition (error) that has occurred in a piece of code.
What is the difference between checked and unchecked exceptions in JAVA?
The java.lang.Throwable class is the root class of Java Exception hierarchy which is inherited by two subclasses: Exception and Error. A hierarchy of Java Exception classes are given below:
Types of exceptions in JAVA
In JAVA, exceptions can be divided into three groups.
Checked Exceptions - The exceptions which are checked at the compile time are called Checked Exceptions; e.g. IOException, SQLException etc. Checked exceptions are checked at compile-time.
Example –
FileNotFoundException is a checked exception in Java. Anytime we want to read a file from a filesystem, Java forces us to handle error situations where files may not be present in place.
Try to read file with handle FileNotFoundException |
public static void main(String[] args) { FileReader file = new FileReader("somefile.txt"); } |
Java will throw a compile time error with a message – Unhandled exception type FileNotFoundException. |
Unchecked Exceptions - The exceptions which are not checked at the compile time are called Unchecked Exceptions; e.g. ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException etc.
Example –
private static void divideByZero() {
int numerator = 1;
int denominator = 0;
int result = numerator / denominator;
}
The above piece of code will throw an unchecked exception (ArithmeticException) if not handled properly; because divide by zero is not allowed in simple arithmetic.
Error - Errors in JAVA are irrecoverable, which means they cannot be handled at all. OutOfMemoryError, VirtualMachineError, AssertionError etc. are examples of Runtime Exceptions.
What is Throwable class in JAVA?
The Throwable class is the superclass of all errors and exceptions in the Java language. Only objects that are instances of this class (or one of its subclasses) are thrown by the Java Virtual Machine or can be thrown by the Java throw statement. Similarly, only this class or one of its subclasses can be the argument type in a catch clause.
Briefly describe all the keywords in JAVA exception handling.
Java exception handling is managed via five keywords: try, catch, throw, throws, and finally. Briefly, here is how they work. Program statements that we want to monitor for exceptions are contained within a try block. If an exception occurs within the try block, it is thrown. Our code can catch this exception (using catch) and handle it in some rational manner. System-generated exceptions are automatically thrown by the Java run-time system. To manually throw an exception, use the keyword throw. Any exception that is thrown out of a method must be specified as such by a throws clause. Any code that absolutely must be executed after a try block completes is put in a finally block.
How does try-catch work together?
As mentioned earlier, inside the try block we put risky code, which may cause an exception. catch block is responsible to hold the exception thrown inside try block and gracefully exit/continue the program.
Let us see try-catch in action using an example.
public class TryCatchExample {
public static void main(String[] args) {
try
{
int data=50/0; //may throw exception
}
//handling the exception
catch(ArithmeticException e)
{
System.out.println(e);
}
System.out.println("rest of the code");
}
}
Output –
java.lang.ArithmeticException: / by zero
rest of the code
Explanation
We have put the risky code (divide by zero) inside the try block. When dividing by zero throws an exception, the subsequent catch block holds it and performs some action (which is optional) and continues the execution. That is why try/catch block is so important in the context of exception handling, it lets the execution continue instead of abruptly stopping the program.
Note that any exception can be held by catch block by object of specific exception class (‘e’ in the above example, which is an object of ArithmeticException) or any other superclass of that class (RuntimeException, which is superclass of ArithmeticException class or Exception, which is superclass of RuntimeException class).
Can we have multiple catch statements for a single try block?
A try block can be followed by one or more catch blocks. Each catch block must contain a different exception handler. So, if we have to perform different tasks at the occurrence of different exceptions, we need to use a multi-catch block.
Example
public class MultipleCatchBlock3 {
public static void main(String[] args) {
try{
int a[]=new int[5];
a[5]=30/0;
System.out.println(a[10]);
}
catch(ArithmeticException e)
{
System.out.println("Arithmetic Exception occurs");
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("ArrayIndexOutOfBounds Exception occurs");
}
catch(Exception e)
{
System.out.println("Parent Exception occurs");
}
System.out.println("rest of the code");
}
}
Output
Arithmetic Exception occurs
rest of the code
Explanation
In the try block, there are 2 statements which cause exceptions. But as soon as the first exception is encountered, the catch block is invoked and the corresponding exception handler is searched. In the above example, when an arithmetic exception occurs, the exception goes to the first catch block and executes the code inside it and then executes the rest of the program.
When you use multiple catch statements, it is important to remember that exception subclasses must come before any of their super classes. This is because a catch statement that uses a superclass will catch exceptions of that type plus any of its subclasses. Thus, a subclass would never be reached if it came after its superclass. Further, in Java, unreachable code is an error.
As of JAVA 7; we do not specifically need to specify all catch statements with subclass of Exception class, we can do that by using bitwise or operator like below:
catch(ArrayIndexOutOfBoundsException | ArithmeticException e) {
System.out.println(e);
This is similar to:
catch (ArithmeticException e){
System.out.println (e);
} catch (ArrayIndexOutOfBoundsException arr)
{
System.out.println (e);
}
Is it possible to have multiple try blocks with only one catch block in java?
We cannot have multiple try blocks with a single catch block. Each try block must be followed by catch or finally. Still if you try to have a single catch block for multiple try blocks a compile time error is generated.
What is nesting of try catch blocks?
When a try-catch block is present inside another try-catch block then it is called the nested try catch block. Each time a try block does not have a catch handler for a particular exception, then the catch blocks of the parent try block are inspected for that exception, if a match is found that that catch block executes.
If none of the catch blocks handles exceptions then the system generated message would be shown for the exception, like what we see when we don’t handle exceptions.
Example
public class NestingDemo {
public static void main(String args[]) {
// main try-block
try {
// try-block2
try {
// try-block3
try {
int arr[] = { 1, 2, 3, 4 };
/* Trying to display the value of an element which doesn't exist. The code should throw an exception */
System.out.println(arr[10]);
} catch (ArithmeticException e) {
System.out.print("Arithmetic Exception");
System.out.println(" handled in try-block3");
}
} catch (ArithmeticException e) {
System.out.print("Arithmetic Exception");
System.out.println(" handled in try-block2");
}
} catch (ArithmeticException e3) {
System.out.print("Arithmetic Exception");
System.out.println(" handled in main try-block");
} catch (ArrayIndexOutOfBoundsException e4) {
System.out.print("ArrayIndexOutOfBoundsException");
System.out.println(" handled in main try-block");
}
}
}
Output
ArrayIndexOutOfBoundsException handled in main try-block
Explanation
The exception is neither handled in the catch block with respect to try3, try2 or try1 because of type mismatch. Also, it does not get handled by the main catch block with Arithmetic Exception. Finally, it is caught by the main catch block of ArrayIndexOutOfBoundsException (e4).
What is the throw keyword and what is the use of it?
The throw keyword is used to throw an exception from a block of code in JAVA. Both checked and unchecked exceptions can be thrown.
throw keyword is mostly used to throw custom exceptions but throwing built in exceptions is also possible.
Example
public class Exe0 {
static void proc()
{
try{
throw new NullPointerException();
}catch(NullPointerException e)
{
System.out.println("Inside the method");
throw e;
}
}
public static void main(String[] args) {
try
{
proc();
}catch(NullPointerException e)
{
System.out.println("Inside main");
}
}
}
Output
Inside the method
Inside main
In the above example, the first thrown exception is caught by its catch block. The other exception which is thrown in catch is caught in the catch block of the main method.
Explain throws keyword?
If a method can throw an exception that it does not handle, then it must specify the behavior so that the caller methods can guard themselves against the exception.
You do this by including a throws clause in the method’s declaration. A throws clause lists the types of exceptions that a method might throw.
public class Exe {
static void proc() throws NullPointerException
{
throw new NullPointerException();
}
public static void main(String[] args) {
try
{
proc();
}catch(NullPointerException e)
{
System.out.println("Inside main");
}
}
}
Output
Inside main
In the above example, the proc () method throws an exception which is not handled by itself, rather by its caller, main() method.
Explain finally keyword?
finally creates a block of code that will be executed after a try/catch block has completed and before the code following the try/catch block. The finally block will execute whether or not an exception is thrown. If an exception is thrown, the finally block will execute even if no catch statement matches the exception.
Finally block I optional, but a try block must either be followed by a catch or a finally block.
A catch and finally can both be present; but sequence should be catch>finally and not vice versa.
We normally put all important code which needs to be executed irrespective of whether an exception occurs or not, the exception is handled or not. For example, closing a database connection etc.
Example
class TestFinally{
public static void main(String args[]){
try{
int val=20/0;
System.out.println(val);
}
catch(NullPointerException e){System.out.println(e);}
finally{System.out.println(“in finally block");}
System.out.println("rest of the code");
}
}
Output
in finally block
Exception in thread main java.lang.ArithmeticException:/ by zero
Explanation
In the above program, the exception that occurs is not handled by NullPointerException, which means the program ends abruptly, but before that, finally block is executed.
What is exception propagation?
An exception is first thrown from the top of the method call stack, and moves to the bottom of the stack gradually, until it is handled.
Only unchecked exceptions can be propagated (forwarded to the down of the stack), not checked exceptions.
Example
class ExceptionPropagation{
void method1(){
int val=20/0;
}
void method2(){
method1();
}
void method3(){
try{
method2();
}catch(Exception e){System.out.println("exception handled in method3");}
}
public static void main(String args[]){
ExceptionPropagation obj=new ExceptionPropagation ();
obj. method3();
System.out.println("normal flow...");
}
}
Output
exception handled in method3
normal flow...
Explanation
Even though the exception occurred in method1, it is caught in method3.
What are custom exceptions and how to create them?
Although Java’s built-in exceptions handle most common errors, you will probably want to create your own exception types to handle situations specific to your applications. This is quite easy to do: just define a subclass of Exception (which is, of course, a subclass of Throwable).
import java.util.ArrayList;
import java.util.Arrays;
// create an exception class
class CustomException extends Exception {
public CustomException(String message) {
// call the constructor of Exception class
super(message);
}
}
class Main {
ArrayList<String> languages = new ArrayList<>(Arrays.asList("Java", "Python", "JavaScript"));
// check the exception condition
public void checkLanguage(String language) throws CustomException {
// throw exception if language already present in ArrayList
if(languages.contains(language)) {
throw new CustomException(language + " already exists");
}
else {
// insert language to ArrayList
languages.add(language);
System.out.println(language + " is added to the ArrayList");
}
}
public static void main(String[] args) {
// create object of Main class
Main obj = new Main();
// exception is handled using try...catch
try {
obj.checkLanguage("Swift");
obj.checkLanguage("Java");
}
catch(CustomException e) {
System.out.println("[" + e + "] Exception Occured");
}
}
}
Output
Swift is added to the ArrayList
[com.informatica.cdi.automation.ui.robot.MAT.CustomException: Java already exists] Exception Occurred
Explanation
We have created a class for custom exceptions called CustomException, which inherits Exception class (this is mandatory). The constructor of this class has a parameterized constructor, which calls the superclass constructor.
Inside the method checkLanguage(), we have checked the exception condition, and if the exception occurs, the try..catch block handles the exception.