Lesson 3 | Error detection and handling in Java |
Objective | Be able to explain How Java Separates Error Detection from Error Handling. |
How Java Separates Error Detection from Error Handling
With exceptions, rather than
assuming the constructor knows what the program using it wants (null, zero (0), or something else), the constructor has another option:
- it can indicate that there was an error, and it does this by throwing an exception.
- Throwing an exception returns control to the calling program and executes a block of code specifically set up to handle error conditions.
Error detection and handling in Java
The great advantage of this scenario is that it cleanly separates the detection of the error from the handling of the error.
There are no error codes being passed back as return values and no guesses on the part of the code that detects the error.
The code detecting the error simply returns control back to the code invoking it. The code invoking it then handles the error as it sees fit.
Since Java is an object-oriented language, it represents an exception as an instance of class Exception. There are also a variety of Exception subclasses that can be used to indicate a particular type of exception.
For example, there are IOExceptions, NumberFormatExceptions, and CloneNotSupportedException.
The calling code can determine the type of exception that occurred based on the particular class an exception object belongs to.
What Is an Exception?
An exception is a condition that may arise during the execution of a Java program when a normal path of execution is not defined. For example, a Java program may encounter a numeric expression that attempts to divide an integer by
zero. Such a condition may occur during the execution of the following snippet of code:
int x = 10, y = 0, z;
z = x/y; // Divide-by-zero
The statement z = x/y attempts to divide x by y. Because y is zero, the result of x/y is not defined in Java. Note that dividing a floating-point number by zero, for example 9.5/0.0, is defined and it is infinity. In generic terms, the abnormal condition, such as dividing an integer by zero, can be phrased as follows: An error occurs when a Java program attempts to divide an integer by zero.
The Java programming language describes the above error condition differently. In Java, an exception is thrown when a Java program attempts to divide an integer by zero.
This means an abnormal condition in a program has occurred. What happens after the abnormal condition occurs in a program?
You need to handle such an abnormal condition in the program. One of the ways to handle it is to check for all possibilities that may lead to an abnormal condition, before performing the action. You may rewrite the above code as follows:
int x = 10, y = 0, z;
if (y == 0) {
Error Handling versus Exceptions
Notice that when you added error handling to your four lines of pseudocode, the code bloated to over twenty lines.
The worst thing about the above code is that the code that performs the action has been cluttered with errorhandling code. It has also introduced many nested if-else statements. resulting in spaghetti code.
In the last two examples, you saw that the way of handling errors that uses if-else statements is not elegant and maintainable. Java has a better way to handle errors: by separating the code that performs actions from the code that handles errors.
In Java, we use the phrase "exception" instead of "error" to indicate an abnormal condition in a program; the phrase "exception handling" is used instead of the phrase "error handling"
In general, we say that an error occurs and you handle it. In Java, we say that an exception is thrown and you catch it.
This is the reason that exception handling is also called catching an exception. The code that handles the exception is known as an exception handler. You could rewrite the above pseudocode using Java syntax (not full-fledged Java code, though) as follows:
try {
// 1) Connect to the database
// 2) Fetch employee record
// 3) Update employee salary
// 4) Commit the changes
}
catch(DbConnectionException e1){
// Handle DB Connection exception here
}
catch(EmpNotFoundException e2){
// Handle employee not found exception here
}
catch(UpdateFailedException e3){
// Handle update failed exception here
}
catch(CommitFailedException e4){
// Handle commit failed exception here
}
Observe the structure of the code, which allows for separation of the code that performs actions from the code that handles exceptions.
The code that performs the actions is placed inside a try block and the code that handles the exception
is placed inside a catch block. You will observe that this code is much better in terms of elegance and maintainability
compared to the previous attempt in which you had to write many if-else statements to achieve the same.