-
Notifications
You must be signed in to change notification settings - Fork 0
Exception Handling
An exception is an unexpected or error condition. For example, if you create a system for a user to enter their name then you output their name back to them. Now let's also say that you have a user that inputs a number instead of text. The most likely thing that will happen is that you will receive and error. This is because the program was only written to handle text. When you input a number instead it does not know what to do with this data and it crashes. Since the user enters a number instead of text was unexpected it is an exception.
The process of resolving and managing exceptions is called exception handling. In Java, there are two basic classes of errors: Error and Exception. The error is used for problems that are more serious. Exceptions, however, are less serious and usually can be easily fixed. Let's take the following code for example:
import java.util.Scanner;
public class Exception {
public static void main(String args[]){
Scanner keyboard = new Scanner(System.in);
int numberOne;
int numberTwo;
int result;
System.out.print("Enter your first number: ");
numberOne = keyboard.nextInt();
System.out.print("Enter second number: ");
numberTwo = keyboard.nextInt();
result = numberOne + numberTwo;
System.out.println(result);
}
}
This above code is normal enough. It asks the user to enter two numbers, adds the number together and outputs the result to the user. However, let's say that a user inputs a name instead of a number then they will be greeted with the following error message when they try to run the program.
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at javadoc.Exception.main(Exception.java:22)
This is what is know as a stack trace. This is how your compiler tries to help you find the source of the exception so that you can fix it. On the first line, you can see that the compiler tells the user where the error has happened. In this case, it was the main method. Next, it tells you the type of exception has occurred. In this case, it is an InputMismatchException. This happens when the data type that is received does not match the data type that the program is asking for. There are many other exception types such as an ArithmeticException, ArrayIndexOutOfBoundsException, and NullPointerException. These exceptions can be looked up at your own convenience.
Using a try-catch is a very common way to handle exceptions. What you do with a try catch is that you try certain blocks of code and then you catch any exceptions or errors that may have occurred. It is also important to know that one catch block can only catch one type of exception. The format of a try-catch looks like this:
try
{
//statement that may throw an error
}
catch(Exception exceptionType)
{
//what to do if the exception is caught
}
Now if you take the code above that through the original error and put it into the try...catch statement it would look like this.
import java.util.Scanner;
import java.util.InputMismatchException;
public class Exception {
public static void main(String args[]){
Scanner keyboard = new Scanner(System.in);
int numberOne;
int numberTwo;
int result;
try{
System.out.print("Enter your first number: ");
numberOne = keyboard.nextInt();
System.out.print("Enter second number: ");
numberTwo = keyboard.nextInt();
result = numberOne + numberTwo;
System.out.println(result);
}
catch(InputMismatchException mistake){
System.out.println("An exception was caught");
}
}
}
Output
Enter your first number: 23
Enter second number: bob
An exception was caught
As you can see the catch block catches the InputMismatchException exception. As you can also see that the imported the exception class for that specific example. Without this import, we cannot catch that error.
As you can see catching exceptions is a good way to make you program more robust. As I said before there are many types of exceptions. You may write a program that you want to use to divide one number by another number. In this case, you could run into at least two exceptions. You could run into an InputMismatchException or you could get an ArithmeticException if you try to divide a number by zero. To catch these two exceptions you would need two separate catch blocks. Catch blocks are executed in sequence until the compiler finds the appropriate catch block and executes it. Any catch blocks after the one that is executed are skipped over. For the division program, the try...catch blocks would look like this.
import java.util.Scanner;
import java.util.*;
public class Exception {
public static void main(String args[]){
Scanner keyboard = new Scanner(System.in);
int numberOne;
int numberTwo;
int result;
try
{
System.out.print("Enter your first number: ");
numberOne = keyboard.nextInt();
System.out.print("Enter second number: ");
numberTwo = keyboard.nextInt();
result = numberOne / numberTwo;
System.out.println("Your answer is " + result);
}
catch(InputMismatchException wrongData)
{
System.out.println("Wrong Data Type entered");
}
catch(ArithmeticException wrongNumber){
System.out.println(wrongNumber.getMessage());
}
}
}
Output
Input wrong Data Type
Enter your first number: 45
Enter second number: text
Wrong Data Type entered
Trying to divide by zero
Enter your first number: 65
Enter second number: 0
/ by zero
As you can see the catch blocks catch not only the InputMismatchException but also the ArithmsticException. You can also see that I used the .getMessage() method in the second catch block. This method gets the message that the exception throws and outputs it to the user. This can be helpful for informing the user where they might have done something wrong. This is only part of the power of try...catch blocks. By using more advanced concepts you can make your program almost foolproof.
Let's say that you have a program that you think will throw an exception. If the exception is caught within the same method that it happens then the program can easily execute the try...catch blocks. However, if an exception is throw in one method, but it going to be caught in another then you must use a throw clause. This is known as exception specification. For example, lets say we a method with the grades of a class.
public class gradeList
{
public static final int[] grades = {90, 80, 70, 60, 50};
public static void displayGrades(int examScore) throws IndexOutOfBoundsExcption
{
System.out.println("Your grade is " + grades[examScore]);
}
{
As you can see the throws clause specifies that the displayGrades method may throw an IndexOutOfBoundsException. Now when used in the other methods this exception will be caught properly.
Even though there are over 40 categories of exceptions in Java there is now way that the creators of Java could write something for every possible exception that may occur. Since Java is so versatile it is possible to get multiple unknown exceptions. To create your own exception you will need to extend from either the Exception of Error subclasses. Below is a table of the 4 Exception class constructors.
Contructor | What it does |
---|---|
Exception() | Contructs a new Exception object with null as its detailas |
Exception(String message) | Constructs a new object with the specified detail message |
Exception(String message, Throwable cause) | Constructs a new object with the specified detail message and cause |
Exception(Throwable cause | Constructs a new object with the specified cause and a detailed message of cause.toString() which contains the detail message of cause, or null if cause argument is null |
As you can see even though there are only 4 constructors there are plenty of ways that you can use them. So, as an example, let's say that we have a program that we want to check to make sure a user's bank account balance is not too low. Since there is now exception class to catch this we would need to create our own.
public class LowBankBalance extends Exception
{
public LowBankBalance()
{
super("Customer balance is too low");
}
}
Note that we are extending the Exception class
Now that we have our homemade exception class. We need to use it. For you will have to make a CustomerAccount class.
public class CustomerAccount{
private int acctNum;
private double balance;
public static double LOW_BANK_LIMIT = 1000.00;
public CustomerAccount(int num, double bal)throws Exception.LowBankException{
acctNum = num;
balance = bal;
if(balance < LOW_BANK_LIMIT) {
throw (new Exception.LowBankException());
}
}
}
So now that we have both our outside classes we will need to implement then inside of the main class.
import javax.swing.*;
public class Exception {
public static void main(String args[]){
int num = 4;
double balance = 500.00;
try{
CustomerAccount ca = new CustomerAccount(num, balance);
}catch(LowBankException lbe){
System.out.println("Customer has a balance that is to low");
}
}
}
Now if we run this app we can test the output of the exception class.
Output
Customer has a balance that is to low.