Chapter 12-A Handling Errors In chapter 6 we saw that syntactic errors are caught by the compiler. Sometimes we may have a hard time ing to correct them, but we know they exist because the program does not compile. On the other hand, logical errors are more difficult to detect, among other things because they can arise from different reasons, like bad solution to the original problem (it works in some situations giving the right answer, but not in others), an object is asked to do some it is not intended to do, just because it is unable to do it, or because it does not fit the aim of the class designer, or a combination of these types of problems. But even if the program is well tested using the techniques we learned in chapter 6, it could fail, due to circumstances beyond the control of the programmer. In this chapter we to use a strategy of defensive programming, where we to foresee and take care of error situations that may happen during the execution of a program, so that there is information left about the problem, and the program does not fail abruptly. Java uses the exception mechanism to detect and report errors. Using exceptions allows a program to fail smoothly. An exception is an error condition that interrupts the normal flow of the program. It occurs when the program executes the throw keyword. This throw statement invokes the associated catch block. If there is a catch in the current method, the control passes immediately to goes to the calling method, without returning a value (if one was needed), and then Java looks for a catch block in the calling method. If it does not find any, it passes control to the method that invoked the calling method and so on, until Java finds a catch block that can handle the error. Therefore when an exception is thrown, two different things have to be considered. How the exception affects the throwing method and how it affects the caller method. Effect in the throwing method: If an exception is thrown, the throwing method does not continue with its execution, so even if the method requires to return a value, no return statement needs to be executed. Therefore, the method does not need to have a return statement following the line throwing the exception, in the branch that follows that part of the code. Effect in the calling method: As we mentioned before, the effect will depend upon a catch block was written for that exception. If there is no catch in the calling method, the program will terminate with a general indication of what went wrong. The key work here is general, because we didn t catch the exception specifically.
Note that the constructor of an object is very vulnerable if it receives values through its parameters. It does not have any control if the parameters are bad, and the bad initial state of the object will influence all further results. Exception is a subclass of the superclass Throwable. The other subclass is Error. The Error class deals with errors that are beyond the control of the programmer. Exceptions can be checked or unchecked. All the subclasses of the standard (sub)class RuntimeException are unchecked exceptions. All the other subclasses from the superclass Exception are checked ones. It is worth to note that unchecked exception should be used, generally, for situations that should be avoided in normal circumstances (going outside the range of an array, passing a null value when a valid address is required, etc..) On the other hand, checked exceptions could be used for unpredictable situations, like a disk being full, or a line is not connected. But this is an informal rule. Sometimes it is difficult to decide which kind of exception one should use. Why are we making such a fuss about checked and unchecked exceptions? Well, the formal handling of both of them is very different, and we need to outline the differences. In fact a checked exception requires an explicit exception handler. On the other hand, both checked and unchecked exceptions follow the same pattern on the method that throws the exception. Throwing an exception: To throw an exception and exception object is created and then it is thrown. throw new ExceptionType( optional string ); Example: public ComplexNumber Divide(double d) if (d == 0) throw new ArithmeticException( dividing by zero ); return new ComplexNumber(m_dReal/d, m_dimag /d) Unchecked exceptions: They are very easy to use, because the compiler does not enforce almost any rules on them. In general we assume that no program continuation should occur when an unchecked exception occurs, and the method caller will not have a specific catch for it.
On the other hand, if there is a need to catch an unchecked exception, an exception handler can be written to do the job. Checked exceptions: With the checked exception there are several rules that we have to follow both in the method that throws this type of exception, and in the caller of that method. The method that throws the exception has to declare it in its header, adding the throws clause at the end of it. Example: public void Withdrawal (double damount) throws InsufficientFundsException if (m_dbalance < damount) throw new InsufficientFundsException(this, damount); m_dbalance - = damount; And of course, we must declare the new exception class InsufficientFundsException, who generated the object to be thrown. public class InsufficientFundsException extends Exception private BankAccount m_ba ; // this is the account having the insufficient funds private double m_dwithdrawalamount; // Constructor public InsufficientFundsException( BankAccount ba, double theamount) super( Insufficient funds in the account ); m_ba = ba; m_dwithdrawalamount = theamount: public String tostring() StringBuffer sb = new StringBuffer(); sb.append( Insufficient funds in account ); sb.append(m_ba.getaccountnumber() ); sb.append( \n Balance was ); sb.append(m_ba.getbalance() );
sb.append( \nwithdrawal was ); sb.append(m_dwithdrawalamount); return sb.tostring(); // End of tostring method Note that a single method can throw more than one exception. Catching exceptions If we need an exception handler, we must write a block and a catch block. Statements that will be protected by the exceptions catch Reports about the occurred exception, and how to recover from it The block is the set of statements containing the calls to the methods that can fail due to an exception. The catch block will to catch exceptions from any statement within the previous block. Example 1: public class test public static void main(string[] args) BankAccount.newWithdrawal(100.0); catch(exception e) System.out.println(e.toString() ); // End of main // End of test // Generic exception Example 2: public class test
public static void main(string[] args) BankAccount.newWithdrawal(100.0); catch(insufficientamountexception ife) System.out.println(ife.toString()) catch(exception e) System.out.println(e.toString() ); // End of main // End of test // Specific exception // Generic exception It should be noted that when several statements are in the block, the one that called the method that throws the exception is the last one to be executed in the block. Control passes immediately to one of the catch blocks, the one whose parameter matches the exception object. In fact Java compares the argument of the first catch to the exception object, if a match is found, that catch block is executed, otherwise, it goes to the next catch, until it finds a match. Java allows a third component to the pair block and a catch block. It is the finally block, which is optional. Statements that will be protected by the exceptions catch Reports about the occurred exception, and how to recover from it finally Statements to be executed no matter if the exception is caught or not. The finally block is a block of code that will be executed before control exits the method, no matter what. I couldn t find any good example of using the finally block. So I have this simple example, in which we want to read an integer that represents the index value in an array of 100 elements. num = scanner.nextint();
if (num > 100) throw new Exception( Out of bound ); catch(inputmismatchexception e) scanner.next(); System.out.println( Not an integer); catch(exception e) System.out.println( Error: + e.getmessage( ) ); finally System.out.println( DONE ); The important thing is to understand the different possibilities. If no error in input occurs, then DONE will be printed. If an error in input occurs, then the printout would be either Not an integer DONE Or Error: Out of bound DONE