9.EXCEPTION HANDLING
What is Exception?
In our daily-to-daily life, we come across several situations where things don’t go as planned.
You planned for a long trip on your car. However, when you go on the trip, your car breaks down. This can break your trip plans. Maybe you would like to cut short your trip.
You went to a restaurant on your birthday only to find that it is closed. A boy in class X board fails 2 times. His plan to study in XI is delayed by one year.
Think of various other examples in real life. These deviations are called exceptions.
Similarly, while the CPU executes a program, there is a possibility that ‘execution’ does not end completely in a normal way or as the user of the program was expecting.
Let’s take a few examples. To open your account on Facebook, you need to enter username and password before you can access your account.
What is normal? → User enters correct username & its corresponding password.
What is exception scenario?
- User enters wrong username
- User enters wrong password
In both the cases, user will not be able to see the landing page (new tab, post).
- You open the account of a friend who has blocked you → You will not be able to open.
- You have 5000 friends on Facebook. You send a friend request → You will not be able to do so.
Let’s understand how the exception can occur in a Java program. A very popular example is being shown here.
class Division {
public static void main(String[] args) {
int dividend;
int divisor;
float result;
Scanner s = new Scanner(System.in);
dividend = s.nextInt(); // ①
divisor = s.nextInt(); // ②
result = dividend / divisor; // ③
System.out.println("Result = " + result); // ④
}
}
This program takes two numbers as dividend & another one as divisor.
This program will run normally & give the answer for the question. No problem will be there. But what if the divisor is 0? This is the exception scenario. CPU will not be able to divide a no. by 0. Hence, it will not be able to calculate the value of the variable “result”. The control will never reach at line #④. Before that at line #③, exception will occur & your program will terminate abnormally. You can try running the program.
Since Java is OOPs, everything is represented by class. Here, ArithmeticException is also represented by a distinct class present in Java’s library. For the above exception is thrown by Java through a class called ArithmeticException class. Normally, the class which denotes an exception has Exception as the suffix. Hence, an object of the ArithmeticException is thrown to JVM when division by 0 happens.
We hope that the basic concept of exception is clear.
Just like ArithmeticException, there are various such exception classes provided by Java in its library. These classes can be used to throw exceptions at relevant scenarios in our programs. In large applications like a banking portal or the software used by ISRO/NASA you will find the mention of hundreds of exceptions.
Let’s see few exceptions provided by Java library. Mentioning only those which can be easily understood at this point of time.
- NullPointerException → We know that a class has variables & methods. To use a method, we need to call it through an object of the class in which that method resides.
class Adder {
int add(int firstNo, int secondNo) {
int sum = firstNo + secondNo;
return sum;
}
}
We have a class named Adder and it has just one method. This method takes two arguments, does the sum of these two arguments & returns the same.
I want to add two numbers. How can I use this method to find the sum? I will create a Driver class (the class with main() method in it) & will call the method. Look carefully how we do it.
class AdderDriver {
public static void main(String[] args) {
// We will create an object of Adder class
Adder adderObject = new Adder();
// We have these two numbers, whose sum we want to know
int firstNumber = 50;
int secondNumber = 100;
// This is how we call (invoke) the method of the class
int sum = adderObject.add(firstNumber, secondNumber);
System.out.println("Sum = " + sum);
}
}
We have already studied about classes and objects. The object of a class holds the ‘state’ (its own copy of the variables defined in the class) and the methods are the behaviour of the object.
Donald Trump is an object of Man class. This object has attributes like it has been born, she has had kids. This object has behaviours like it gives speeches, it walks, it breathes etc.
Similarly, Vladimir Putin is another object of the Man class. Putin is an object of more age, short, today etc.
So, here we have the object of Adder class named adderObject. To exhibit the behaviour of this object, adderObject.add() method is called through the object name.
This will run fine & will return the summation of the two numbers. However, the condition is that adderObject should not be null. If adderObject is somehow null, the CPU will not be able to execute the method. In this case, NullPointerException will be thrown.
When we are doing adderObject.add(firstNumber, secondNumber) whereas adderObject is null, we are doing the same thing as asking a dead man to show behaviour.
Analogy: Man mahatmaGandhi = new Man();mahatmaGandhi.speak();
This will throw an exception as a dead man cannot speak.
- SQLException: You might be aware that data to be stored permanently is stored in database which resides in secondary storage like Hard Disk, Pendrive, memory card etc. We need to write Java code for connecting to a database & to insert the data generated by our Java program into the database. There are many possibilities of exception during execution of such code. Such exceptions tend to be SQLException.
Error vs Exception
You might think it as error scenarios, then why do we have a dedicated term ‘exception’ for such scenarios. Well, in Java, Error & Exception are two different entities. That’s why Error and Exception are two different classes provided by Java Library.
Any Exception (like the ones we saw above) which too are provided by Java Library. These exceptions have also classes & these classes are child classes of Exception class.
Exception is parent of:
- SQLException
- NullPointerException
- Even you can create your own Exception class.
Similarly, Java library provides Error class. What is why Java set them (Error & Exception) different?
Errors are more severe than Exceptions. Suppose using Java, you are creating an online test portal. The error scenarios which can come within the application i.e. in the code which you wrote are more likely Exception. The error scenarios which can come outside your application realm are more likely Error.
We know that JVM runs the Java programs we wrote in the online test portal & entire portal application is running on a server. So, think of scenarios like:
- Too many people (say 10000) applicants are taking exams at the same time. The server has only 8GB RAM. So what will happen? JVM will not be able to respond properly to all the requests it received from the application because the server resource (RAM) is falling short! This is not an Exception scenario but Error scenario. This is a severe problem where you might need to add more RAM.
- JVM while running a Java program creates objects of the classes in the heap section of the RAM. It is possible that you defined very small memory for heap (say 512 MB) but because of bad program you wrote a lot of objects are getting created. So what will happen? That memory will not be available to JVM so it can run on the system. So it will lead to OutOfMemoryError. Now this is a class provided by Java Library to indicate this problem & it is a child class of Error class.
- NoClassDefFoundError is another Error which may occur when JVM tries to load the class (i.e. class file) but it couldn’t find it. It might be because build did not happen correctly. So we need to make sure that the Java classes are built properly.
As you develop Java applications you will come across these Errors & you will come to know more.
We now know that Error & Exception are classes. Let us tell you that these two classes are child classes of another class called Throwable provided by Java library.
So now we can structure it like this:
Throwable (is parent)
├── Error (is parent of)
│ ├── OutOfMemoryError
│ └── NoClassDefFoundError
└── Exception (is parent of)
├── SQLException
├── NullPointerException
└── and so on
Java library provides a lot of Exception classes. The main goal here is that if you want to create your own Exception, you can do that too.
However, we should know one more classification – all the exceptions can be categorized into two categories.
1. Checked Exception: These are the exceptions which are thrown or reported by the compiler during compile time. If an exception of this type occurs then you have to handle it in code so that it gets successfully loaded into Java Byte Code (.class) file.
If you are using a text editor, you will get these exceptions when you compile your java file.
If you are using an IDE, you will get it reported as soon as you save that file or even as you type.
Examples of Checked Exceptions:
- SQLException – When you write a code to connect to a database, you must handle SQLException. If in your code, when we say handle SQLException, we mean that you need to write handling piece of code in your java file which will run in case SQLException occurs.
- FileNotFoundException – In Java, we can read a file in Java code. When we write such a code, we must handle this exception.
So in such situations, the program will not compile if you don’t handle checked exceptions.
2. Unchecked Exception – These are the exception classes which JVM will not ask you to handle. Again, “handle” means it will not ask you to write additional piece of code which JVM will forward in case exception occurs. However, this exception may occur at the time the code is executed / your program is executed.
Examples:
- NullPointerException → This is the best example of unchecked exception. Why? Object of the class which could not be instantiated & a method or data member is invoked through that object will cause NullPointerException. It is totally up to your smartness on how to write such a code/program so that NPE doesn’t occur or if it occurs, how neatly you handle it.
- ArithmeticException → We already saw in the beginning. Program will run absolutely fine when divisor is not 0.
- ArrayIndexOutOfBoundsException → Many of the time, during runtime program we access that index of the array which does not exist. e.g. Array as of size 10 & JVM or program tries to access 10th index or 11th index.
User-defined Exception
The various examples we saw are Exception classes provided by Java Library. But the best part is you can also define your own Exception. This too is necessary because the usage of Java is in several areas – if some will use it for developing online test portal, others will use it to create a game. Some will use it to create credit card management application & so on. So the error scenarios will be very different for each field/area. So, Java gives the flexibility of creating your own Exception.
Let’s consider the Online test portal. Suppose we are writing a method which accepts RollNo of the candidate & throws the exception when rollNo is not 10 characters. If rollNo is OK then call another method to return result.
How to define user-defined Exception:
Step 1: Create a new Exception class
Give it a name of your choice. For JVM to understand it as Exception, we write extends Exception.
public class InvalidRollNoException extends Exception {
public InvalidRollNoException(String message) {
super(message);
}
}
We have defined a parameterized constructor of this class. super(message) means when we create an object of this Exception class, the constructor of the super class Exception is invoked.
Step 2: Use this user-defined exception
public class Result {
public String getResult(int rollNo) throws InvalidRollNoException {
if (String.valueOf(rollNo).length() != 10) {
throw new InvalidRollNoException("Roll No is not valid");
} else {
return getResult(rollNo);
}
}
}
Step 3: Since the above method getResult() is throwing this user-defined exception, we need to add following keyword: throws InvalidRollNoException
Step 4: By the way, this new exception is a checked exception & any method which is calling getResult() will have to handle this exception.
Suppose we are calling this method from a main class. There are two ways to handle checked exception.
Using try-catch-finally block
The method which is throwing user-defined exception must be kept inside try block.
Just at the end of try block, write catch block. This block is executed only if the exception occurs in any of the statements in the try block.
finally block is written at the end of catch block. This is always executed (irrespective of whether exception occurred).
public class TestResult {
public static void main(String[] args) {
try {
String rollNo = args[0];
Result result = new Result();
System.out.println(result.getResult(rollNo));
} catch (InvalidRollNoException ine) {
System.out.println("Error! Roll No is not valid.");
} finally {
// This block always executes
}
}
}
We can put as many lines in try block as we want.