Exceptions:
Exception is an abnormal condition that arises when executing a program.
In the languages that do not support exception handling, errors must be checked and handled manually, usually through the use of error codes.
In contrast, Java:
1) provides syntactic mechanisms to signal, detect and handle errors
2) ensures a clean separation between the code executed in the
absence of errors and the code to handle various kinds of errors
3) brings run-time error management into object-oriented programming
Exception Handling:
An exception is an object that describes an exceptional condition (error) that has occurred when executing a program.
Exception handling involves the following:
1) when an error occurs, an object (exception) representing this error is created and thrown in the method that caused it
2) that method may choose to handle the exception itself or pass it on
3) either way, at some point, the exception is caught and processed
Exception Sources:
Exceptions can be:
1) generated by the Java run-time system Fundamental errors that violate the rules of the Java language or the constraints of the Java execution environment.
2) manually generated by programmer’s code Such exceptions are typically used to report some error conditions to the caller of a method.
3)
Exception Constructs:
Five constructs are used in exception handling:
1) try – a block surrounding program statements to monitor for exceptions
2) catch – together with try, catches specific kinds of exceptions and handles them in some way
3) finally – specifies any code that absolutely must be executed whether or not an exception occurs
4) throw – used to throw a specific exception from the program
5) throws – specifies which exceptions a given method can throw
Exception-Handling Block:
General form:
try { … }
catch(Exception1 ex1) { … }
catch(Exception2 ex2) { … }
…
finally { … }
where:
1) try { … } is the block of code to monitor for exceptions
2) catch(Exception ex) { … } is exception handler for the
exception Exception
3) finally { … } is the block of code to execute before the try
block ends
Benefits of exception handling:
Separating Error-Handling code from “regular” business logic code
Propagating errors up the call stack
Grouping and differentiating error types
Termination vs. resumption:
There are two basic models in exception-handling theory.
In termination the error is so critical there’s no way to get back to where the exception occurred. Whoever threw the exception decided that there was no way to salvage the situation, and they don’t want to come back.
The alternative is called resumption. It means that the exception handler is expected to do something to rectify the situation, and then the faulting method is retried, presuming success the second time. If you want resumption, it means you still hope to continue execution after the exception is handled.
In resumption a method call that want resumption-like behavior (i.e don’t throw an exception all a method that fixes the problem.)
Alternatively, place your try block inside a while loop that keeps reentering the try block until the result is satisfactory.
Operating systems that supported resumptive exception handling eventually ended up using termination-like code and skipping resumption.
Exception Hierarchy
All exceptions are sub-classes of the build-in class Throwable.
Throwable contains two immediate sub-classes:
1) Exception – exceptional conditions that programs should catch
The class includes:
a) RuntimeException – defined automatically for user programs to include: division by zero, invalid array indexing, etc.
b) use-defined exception classes
2) Error – exceptions used by Java to indicate errors with the runtime environment; user programs are not supposed to
catch them.
Usage of try-catch Statements:
Syntax:
try {
<code to be monitored for exceptions>
} catch (<ExceptionType1> <ObjName>) {
<handler if ExceptionType1 occurs>
} ...
} catch (<ExceptionTypeN> <ObjName>) {
<handler if ExceptionTypeN occurs>
}
Catching Exceptions:The try-catch Statements
class DivByZero {
public static void main(String args[]) {
try {
System.out.println(3/0);
System.out.println(“Please print me.”);
} catch (ArithmeticException exc) {
//Division by zero is an ArithmeticException
System.out.println(exc);
}
System.out.println(“After exception.”);
}
}
Catching Exceptions:Multiple catch
class MultipleCatch {
public static void main(String args[]) {
try {
int den = Integer.parseInt(args[0]);
System.out.println(3/den);
} catch (ArithmeticException exc) {
System.out.println(“Divisor was 0.”);
} catch (ArrayIndexOutOfBoundsException exc2) {
System.out.println(“Missing argument.”);
}
System.out.println(“After exception.”);
}
}
Catching Exceptions:Nested try's
class NestedTryDemo {
public static void main(String args[]){
try
{
int a = Integer.parseInt(args[0]);
try {
int b = Integer.parseInt(args[1]);
System.out.println(a/b);
}
catch (ArithmeticException e)
{
System.out.println(“Div by zero error!");
}
}
catch (ArrayIndexOutOfBoundsException)
{
System.out.println(“Need 2 parameters!");
}
}
}
Throwing Exceptions(throw):
So far, we were only catching the exceptions thrown by the Java system.
In fact, a user program may throw an exception explicitly:
throw ThrowableInstance;
ThrowableInstance must be an object of type Throwable or its subclass.
Once an exception is thrown by:
throw ThrowableInstance;
1) the flow of control stops immediately
2) the nearest enclosing try statement is inspected if it has a catch statement that matches the type of exception:
1) if one exists, control is transferred to that statement
2) otherwise, the next enclosing try statement is examined
3) if no enclosing try statement has a corresponding catch clause, the default exception handler halts the program and prints the stack
Creating Exceptions
Two ways to obtain a Throwable instance:
1) creating one with the new operator
All Java built-in exceptions have at least two Constructors:
One without parameters and another with one String parameter:
throw new NullPointerException("demo");
2) using a parameter of the catch clause
try { … } catch(Throwable e) { … e … }
Example: throw 1
class ThrowDemo {
//The method demoproc throws a NullPointerException
exception which is immediately caught in the try block and
re-thrown:
static void demoproc() {
try {
throw new NullPointerException("demo");
} catch(NullPointerException e) {
System.out.println("Caught inside demoproc.");
throw e;
}
}
finally:
When an exception is thrown:
1) the execution of a method is changed
2) the method may even return prematurely.
This may be a problem is many situations.
For instance, if a method opens a file on entry and closes on exit; exception handling should not bypass the proper closure of the file.
The finally block is used to address this problem.
The try/catch statement requires at least one catch or finally clause, although both are optional:
try { … }
catch(Exception1 ex1) { … } …
finally { … }
Executed after try/catch whether of not the exception is thrown.
Any time a method is to return to a caller from inside the try/catch block via:
1) uncaught exception or
2) explicit return
the finally clause is executed just before the method returns.
Example Program:
import java.io.*;
import java.lang.*;
import java.util.*;
class exceptionDemo{
public static void main(String args[]){
//code using try-catch block
try
{
int a=0;
int result=20/a;
int[] num=new int[3];
Scanner sr=new Scanner(System.in);
System.out.println("enter a number");
num[0]=sr.nextInt();
}
catch(NumberFormatException ex)
{
System.out.println("Array type mismatched");
}
catch(InputMismatchException ex)
{
System.out.println("Input type mismatched");
}
catch(ArithmeticException e)
{
System.out.println("can not divide with Zero");
}
finally{
System.out.println("this is a final method");
}
}
}
Java Built-In Exceptions
The default java.lang package provides several exception classes, all sub-classing the RuntimeException class.
Two sets of build-in exception classes:
1) unchecked exceptions – the compiler does not check if a method handles or throws there exceptions
2) checked exceptions – must be included in the method’s throws clause if the method generates but does not handle them.
Unchecked Built-In Exceptions
Methods that generate but do not handle those exceptions need not declare them in the throws clause:
1. ArithmeticException
2. ArrayIndexOutOfBoundsException
3. ArrayStoreException
4. ClassCastException
5. IllegalStateException
6. IllegalMonitorStateException
7. IllegalArgumentException
8. StringIndexOutOfBounds
9. UnsupportedOperationException
10. SecurityException
11. NumberFormatException
12. NullPointerException
13. NegativeArraySizeException
14. IndexOutOfBoundsException
15. IllegalThreadStateException
Checked Built-In Exceptions:
Methods that generate but do not handle those exceptions must declare them in the throws clause:
1. NoSuchMethodException
2. NoSuchFieldException
3. InterruptedException
4. InstantiationException
5. IllegalAccessException
6. CloneNotSupportedException
7. ClassNotFoundException
Creating Own Exception Classes:
Build-in exception classes handle some generic errors.
For application-specific errors define your own exception classes. How? Define a subclass of Exception:
class MyException extends Exception { … }
MyException need not implement anything – its mere existence in the type system allows to use its objects as exceptions.
Example: Own Exception
A new exception class is defined, with a private detail variable, a one parameter constructor and an overridden toString method:
class MyException extends Exception{
private int b;
MyException(int a){
b=a;
}
public String toString(){
return "MyException["+b+"]";
}
}
class exceptionOwn{
static void compute(int a)throws MyException{
System.out.println("Called compute("+a+")");
if(a>10)
throw new MyException(a);
System.out.println("Normal exit");
}
public static void main(String args[]){
try{
compute(1);
compute(20);
}
catch(MyException e)
{
System.out.println("Caught "+e);
}
}
}