Showing posts with label Java Exception Handling. Show all posts
Showing posts with label Java Exception Handling. Show all posts

Sunday, 7 June 2015

Java Creating user-defined Exception/Error sub-classes

This is quite easy to do, just define a sub class of Exception/Error class. Your sub-classes do not need to actually implement anything. It is their existence in the type system that allows you to use them as exceptions/errors. The Exception/Error class does not define any methods of its own.

It does, of course, inherit methods provided by Thorwable class.

Extending RunTimeException or any of its sub-classes will create a user-defined unchecked-exception and extending Exception and any other sub-class of exception will create a user-defined checked-exception.  

Example: The following example demonstrates the use of a user-defined checked-exception.

class InvalidMarksException extends Exception

{ InvalidMarksException(String msg)

{ super(msg);

}

}

class MyExceptionDemo

{ static void dispGrade(int marks) throws InvalidMarksException

{ if(marks < 0 || marks > 100)

throw new InvalidMarksException

if(marks >= 75) System.out.println("S");

else if(marks >= 60) System.out.println("A");

else if(marks >= 50) System.out.println("B");

else if(marks >= 33) System.out.println("C");

else System.out.println("F");

("Marks should be in the range 0 to 100");

}

public static void main(String args[])

{ try

{ int marks = Integer.parseInt(args[0]);

dispGrade(marks);

}

catch(InvalidMarksException e)

{ System.out.println(e);

}

}

}


Example: The following example is rewritten here so as to display the marks entered as command line argument along with the error message.

class InvalidMarksException extends Exception

{ int marks;

InvalidMarksException(int marks, String msg)

{ super(msg);

}

public String toString()

{

}

}

class MyExceptionDemo1

{ static void dispGrade(int marks) throws InvalidMarksException

{ if(marks < 0 || marks > 100)

this.marks = marks;

return("InvalidMarksException["+marks+"]:"+getMessage());

throw new InvalidMarksException

if(marks >= 75) System.out.println("S");

else if(marks >= 60) System.out.println("A");

else if(marks >= 50) System.out.println("B");

else if(marks >= 33) System.out.println("C");

else System.out.println("F");

(marks, "Marks should be in the range 0 to 100");

}

public static void main(String args[])

{ try

{ int marks = Integer.parseInt(args[0]);

dispGrade(marks);

}

catch(InvalidMarksException e)

{ System.out.println(e);

}

}

}

Chained Exceptions

The chained exception feature allows you to associate another exception with an exception. This second exception describes the cause of the first exception. For example, imagine a situation in which a method throws an ArithmeticException because of an attempt to divide by zero.

However, the actual cause of the problem was that an I/O error occurred, which caused the divisor to be set improperly.

Although the method must certainly throw an ArithmeticException, since that is the error that occurred. You might also want to let the calling code know that the underlying cause was an I/O error.

To allow chained exceptions, Java 2, version 1.4 added two constructors and two methods to Throwable class. The constructors are shown here:

Throwable(Throwable causeExc)

Throwable(String msg, Throwable causeExc)

In the first form, causeExc is the exception that causes the current exception. That is, causeExc is the underlying reason that an exception occurred. The second form allows you to specify a description at the same time that you specify a cause exception. These two constructors have also been added to the Error, Exception, and RuntimeException classes.

The chained exception methods added to Throwable class are getCause() and init Cause():

Throwable getCause()

Throwable initCause(Throwable causeExc)

The getCause() method return the exception that underlies the current exception. If there is no underlying exception, null is returned. The initCause() method associates causeExc with the invoking exception and returns a reference to the exception. Thus, you can associate a cause with an exception after the exception has been created. However, the cause exception can be set only once. Thus, you can call initCause() only once for each exception object. Furthermore, if the
cause exception was set by a constructor, then you cannot set it again using initCause() method.

In general, initCause() is used to set a cause for legacy exception classes which do not support the two additional constructors described earlier. Most of Java's built-in exceptions do not define the additional constructors. Thus, you will use initCause() if you need to add an exception chain to these exceptions.

Chained exceptions are not something that every program will need. However, in chases in which knowledge of an underlying cause is useful, they offer an elegant solution.

Example:

class ChainExecDemo

{

static void demoproc()

{

NullPointerException e = new NullPointerException("top layer");

e.initCause(new ArithmeticException("Cause"));

throw e;

}

public static void main(String agrs[])

{

char a = 'a';

try

{

demoproc();

}

catch(NullPointerException e)

{

System.out.println(a);

System.out.println(e);

System.out.println("Original Cause : " +e.getCause());

}

}

}

Output:


Note: The NullPointerException constructor is not overloaded to receive cause so the only way to associate cause with it is to make use of initCause() method.

Java finally clause

finally creates a block of code that will be executed after a try/catch block has completed and before the code following the try/catch block.

The finally block will execute whether or not exception is thrown. If an exception is thrown, the finally block will execute even if no catch statement matches the exception.

Any time a method is about to return to the caller from inside a try/catch block, via an uncaught exception or an explicit return statement, the finally clause is also executed just before the method returns. This can be useful for closing file handlers and freeing up any other resources that might have been allocated at the beginning of a method with the intent of disposing of them before returning.

The finally clause is optional. However, each try statement requires at least one catch or a finally clause.

Example:

class FinallyDemo

{ static void procA()

{ try

{ System.out.println("inside procA()");

throw new RuntimeException("Demo");

}

finally

{ System.out.println("procA()'s finally"); }

}

static int procB()

{ try

{ System.out.println("inside procB()");

return(5);

}

finally

{ System.out.println("procB()'s finally"); return(10);

}

}

static void procC()

{ try

{ System.out.println("inside procC()"); }

finally

{ System.out.println("procC()'s finally"); }

}

public static void main(String args[])

{ try

{ procA(); }

catch(Exception e)

{ System.out.println("! Exception caught:"+e); }

int x = procB();

System.out.println("x= "+x);

procC();

}

}

Output:

inside procA()

procA()'s finally

! Exception caught:java.lang.RuntimeException: Demo

inside procB()

procB()'s finally

x= 10

inside procC()
procC()'s finally

Java throw statement

Example: Normally built-in exceptions are thrown by the JVM but user can also create and throw any exception although this is normally not done. The throw statement is needed for throwing user-defined exceptions, which is discussed in a later section.

The following program creates and throws an exception

class ThrowDemo {

static void demoproc() {

try {

int c = 0, a = 0;

if (a == 0)

int b = c / a;

} catch (ArithmeticException e) {

System.out.println("Caught inside demporoc.");

throw e;

}

throw new ArithmeticException("Division by zero");

}

public static void main(String args[]) {

try {

demoproc();

} catch (ArithmeticException e) {

System.out.println("Recaught: " + e);

}

}

}

Output:

Caught inside demporoc.

Recaught: java.lang.ArithmeticException: Division by zero

Example: The following example demonstrates that if a checked-exception is thrown using throw statement then it must either be caught or declared in the throws clause.

import java.io.*;

class ThrowsDemo {

static void throwOne() throws IOException {

System.out.println("inside throwOne");

throw new IOException("Demo");

}

public static void main(String args[]) {

}

}

Output: above program will not compile and result in following compile time error.

throwOne();


Example: The above example is re-written such that the method throwOne() is called in a try block.

import java.io.*;

class ThrowsDemo

{ static void throwOne() throws IOException

{ System.out.println("inside throwOne");

}

public static void main(String args[])

{ try

throw new IOException("Demo");

{ throwOne();

}

catch(IOException e)

{ e.printStackTrace();

}

}

}

Output: results in an exception at run-time.


Friday, 5 June 2015

Java Handling Checked Exceptions

Example: This program also handles the Checked Exceptions. The following program takes names of two files as input and copies the file specified by the first argument to the file specified by the second argument. The number of bytes copied are displayed in the finally block. So number of bytes copied will be displayed even if some abnormal condition terminates the program. The files are also closed in the finally block so that they will always be closed.

It has three handlers to handle the abnormal conditions:

  • One handler will print the usage of the program when the user does not provide both input and output file names.
  • The next handler will notify the user when the input file does not exist.
  • Another handler will print an error message when other I/O exceptions occur.
import java.io.*;

class MyCopy

{ public static void main(String args[])

{ int byte_count = 0;

byte buffer[] = new byte[512];

String input_file = null;

String output_file = null;

FileInputStream fin = null;

FileOutputStream fout = null;

try

{ input_file  = args[0];

output_file = args[1];

fin  = new FileInputStream(input_file);

fout = new FileOutputStream(output_file);

int bytes_in_one_read;

while((bytes_in_one_read = fin.read(buffer)) != -1)

{ fout.write(buffer,0,bytes_in_one_read);

}

}

catch(ArrayIndexOutOfBoundsException e)

{ System.out.println("Use:java MyCopy source target");

}

catch(FileNotFoundException e)//Checked Exception

{ System.out.println("Can't open input file:"+input_file);

}

byte_count = byte_count + bytes_in_one_read;

catch(IOException e) //Checked Exception

{ System.out.println("I/O Exception occurs");

}

finally

{ if(byte_count > 0)

if(fin != null)

if(fout != null)

}

System.out.println(byte_count + " bytes written");

fin.close();

fout.close();

} // end main

} // end class

Note:

1. FileNotFoundException and IOException are checked exceptions and must be handled.

2. It is possible that we handle only IOException as this will also indirectly handle the FileNotFoundException, which is its sub-class.

3. If both IOException and FileNotFoundException are handled then FileNotFoundException must be caught before IOException as it is sub-class of IOException.

Example: The previous example is rewritten to use method:

int copyFile(String input-file, String output-file)

We want that caller of this method should handle the abnormal conditions by itself. Method will not have any error handler for I/O Exception. A throws clause is added to the method declaration to indicate that method can throw exception and caller has to handle this exception. The caller can also throw the exception if it does not want to handle itself.

import java.io.*;

class MyCopy1

{ static FileInputStream fin = null;

static FileOutputStream fout = null;

public static int CopyFile(String input_file, String output_file)

{ int byte_count = 0;

throws IOException, FileNotFoundException

 fout = new FileOutputStream(output_file);

int bytes_in_one_read;

byte buffer[] = new byte[512];

fin  = new FileInputStream(input_file);

while((bytes_in_one_read = fin.read(buffer)) != -1)

{ fout.write(buffer,0,bytes_in_one_read);

byte_count = byte_count + bytes_in_one_read;

import java.io.*;

class MyCopy1

{ static FileInputStream fin = null;

static FileOutputStream fout = null;

public static int CopyFile(String input_file, String output_file)

{ int byte_count = 0;

throws IOException, FileNotFoundException

 fout = new FileOutputStream(output_file);

int bytes_in_one_read;

byte buffer[] = new byte[512];

fin  = new FileInputStream(input_file);

while((bytes_in_one_read = fin.read(buffer)) != -1)

{ fout.write(buffer,0,bytes_in_one_read);

byte_count = byte_count + bytes_in_one_read;

{ int a = args.length;

int b = 42/a;

System.out.println("a = " + a);

try

{ if(a == 1)

a = a/(a-a);

if(a == 2)

{

int c[] = {1};

c[42] = 99;

}

}

catch(ArrayIndexOutOfBoundsException e)

{ System.out.println("Array index out-of-bounds:"+e);

}

System.out.println("Outer Try");

}

catch(ArithmeticException e)

{ System.out.println(e);

}

System.out.println("After Outer Try");

}

}

Note: Nesting of try statement can occur in less obvious ways when method calls are involved.

For example, you can enclose a call to a method within a try block. Inside that method is another try statement. In this case, the try within the method is still nested inside the outer try block, which calls the method.

Example: Previous program is re-written so that the nested try block is moved inside the method nesttry().

class NestTry1

{ static void nesttry(int a)

{ try

{ if(a == 1)

if(a == 2)

{ int c[] = {1};

}

}

catch(ArrayIndexOutOfBoundsException e)

{

System.out.println("Array index out-of-bounds:" + e);

}

a = a/(a-a);

c[42] = 99;

}

public static void main(String args[])

{ try

{ int a = args.length;

int b = 42/a;

System.out.println("a = " + a);

nesttry(a);

}

catch(ArithmeticException e)

{

System.out.println(e);

}

}

}


Java Exception Handling Example

Example: This example demonstrates the action taken by the default error/exception handler when an exception/error occurs and is not handled.

class Exc0

{ public static void main(String args[])

{ int d = 0;

int a = 42/d;

System.out.println("This will not be printed");

}

}

When the Java run-time system detects the attempt to divide by zero, it constructs a new exception object and then throws this exception. This causes the execution of Exc0 class to stop,

because once an exception has been thrown, it must be caught by an exception handler and dealt with immediately.

In this example, we have not supplied any exception handlers of our own, so the default handler provided by the Java run-time system catches the exception. The default handler displays a string describing the exception, prints a stack trace from the point at which the exception occurred, and terminates the program.

Here is the output generated when this example is executed:

Exception in thread "main" java.lang.ArithmeticException: / by zero at Exc0.main(Exc0.java:4)

Example: This example demonstrates the action taken by the default error/exception handler when an exception/error occurs in a method other then main() and is not handled.

class Exc1

{ public static void subroutine()

{ int d = 0;

int a = 42/d;

}

public static void main(String args[])

{ Exc1.subroutine();

}

Output:

Exception in thread "main" java.lang.ArithmeticException: / by zero at Exc1.subroutine(Exc1.java:4) at Exc1.main(Exc1.java:7)

The resulting stack trace from the default exception handler shows how the entire call stack is displayed

System.out.println("This will not be printed");

Using try and catch

Although the default exception handler provided by the Java run-time system is useful for debugging, you will usually want to handle an exception yourself. Doing so provides two

benefits:

  • First, it allows you to fix the error
  • It prevents the program from automatically terminating

Example:

class Exc2

{ public static void main(String args[])

{ int d,a;

try

{ d = 0;

a = 42/d;

System.out.println("This will not be printed");

}

catch(ArithmeticException e)

{ //e.printStackTrace();

//System.out.println(e);

System.out.println(e.getMessage());

}

System.out.println("After catch statement");

}

}

Output

/ by zero
After catch statement

Note: The scope of the catch clause is restricted to those statements specified by the immediately preceding try statement. A catch statement can not catch an exception thrown by another try statement (except in the case of nested try statements). The statements that are protected by try must be surrounded by curly braces.

Example: This example demonstrates that we can continue execution after handling the exception and can execute the code of same try block again if it is part of a loop.

Recovery.java

import java.util.Random;

class HandleError

{

public static void main(String args[])

{

int a=0, b=0, c=0;

Random r = new Random();

for(int i=0; i < 5; i++)

{

try

{

b = r.nextInt();

c = r.nextInt();

System.out.println(b);

System.out.println(c);

a = 12345/ (b/c);

}catch(AirthmeticException e)

{ System.out.println(e.getMessage());

}

System.out.println("a : " + a);

}

a = 0;

}

}

Example:  The following example demonstrates the use of multiple catch clauses.

class MultiCatch

{ public static void main(String args[])

{ try

{ int a=args.length;

System.out.println("a = " + a);

int b = 42/a;

int c[] = {1};

c[42] = 99;

}

catch(ArithmeticException e)

{ System.out.println("Divide by 0: " + e);

}

catch(ArrayIndexOutOfBoundsException e)

{ System.out.println("Array Index Out Of Bound: " + e);

}

System.out.println("After try/catch blocks.");

}

}

Example: The following example throws four types of Runtime Exceptions:

  • ArithmeticException: integer division by zero.
  • NullPointerException: for accessing a field or invoking a method of a ‘null’ object.
  • ArrayIndexOutOfBoundsException: for accessing an array element by providing an index value less than zero or greater than or equal to array size.
  • StringIndexOutOfBoundsException: for accessing a character of a String or StringBuffer with index less than zero or greater than or equal to length of String.

class ExceptionTest

{ public static void main(String args[])

{ for(int i=0; i<4; i++)

{ int k = 0;

try

{ switch(i)

{ case 0: int zero = 0;

case 1: int b[] = null;

case 2: int[] c = new int[2];

case 3: char ch = "abc".charAt(3);

}

k = 911/zero;

break;

k = b[0];

break;

k = c[9];

break;

break;

}

catch (Exception e)

{ System.out.println(e);

}

}

}

}

Output:

java.lang.ArithmeticException: / by zero
java.lang.NullPointerException
java.lang.ArrayIndexOutOfBoundsException: 9
java.lang.StringIndexOutOfBoundsException: String index out of range: 3

Note: In the above example all the exceptions are handled using only one catch block. This is possible because all the exceptions are sub-classes of the Exception class.

Example: The previous example is slightly modified so that all the exceptions are handled separately. This approach allows us to take separate actions for each exception.

class ExceptionTest1

{ public static void main(String args[])

{ for(int i=0; i<4; i++)

{ int k = 0;

try

{ switch(i)

{ case 0: int zero = 0;

case 1: int b[] = null;

case 2: int[] c = new int[2];

case 3: char ch = "abc".charAt(3);

}

k = 911/zero;

break;

k = b[0];

break;

k = c[9];

break;

break;

}catch (ArithmeticException e)

{ System.out.println(e); }

catch (NullPointerException e)

{ System.out.println(e); }

catch (ArrayIndexOutOfBoundsException e)

{ System.out.println(e); }

catch (StringIndexOutOfBoundsException e)

{ System.out.println(e); }

}

}

}

Output:

java.lang.ArithmeticException: / by zero
java.lang.NullPointerException
java.lang.ArrayIndexOutOfBoundsException: 9
java.lang.StringIndexOutOfBoundsException: String index out of range: 3

Example: In case of multiple catches, exception subclasses must come before any of their super classes. This is because a catch statement that uses a super class will catch exceptions of that type plus any of its sub classes. Thus, a sub class would never be reached if it comes after its super class. Further, in java unreachable code is an error.

class ExceptionTest2

{ public static void main(String args[])

{ for(int i=0; i<4; i++)

{ int k = 0;

try

{ switch(i)

{ case 0: int zero = 0;

case 1: int b[] = null;

case 2: int[] c = new int[2];

case 3: char ch = "abc".charAt(3);

}

k = 911/zero;

break;

k = b[0];

break;

k = c[9];

break;

break;

}

catch (Exception e) //Will not compile

{ System.out.println(e);

}

catch (ArithmeticException e)

{ System.out.println(e);

}

}

}

}

Output:

ExceptionTest2.java:23: exception java.lang.ArithmeticException has already been caught

catch (ArithmeticException e)


Java Exception - throw Statement

It is possible for your program to throw an exception/error explicitly, using the throw statement.

The general form of throw is shown here:

throw ThrowableInstance;

Here, ThrowableInstance must be an object of type Throwable or a sub-class of Throwable.

Simple types, such as int or char as well as non-Throwable classes, such as String and Object, cannot be used as exceptions.

There are two ways you can obtain a Throwable object:
  • Using a parameter into a catch clause.
  • Creating one with the new operator.

Java Exception - throws clause

If a method is capable of causing an exception that it does not handle, it must specify this behavior so that callers of the method can guard themselves against that exception. You do this by including a throws clause in the method’s declaration.

A throws clause lists the types of exception that a method might throw.

This is necessary for all exceptions, except those of type Error or RuntimeException, or any of their subclasses. All other exceptions that a method can throw must be declared in the throws clause. If they are not, a compile-time error will result.

General form of method declaration that includes a throws clause is:

modifiers return-type method-name(parameter-list) throws Exception-list

{

//body of method

}

Here exception-list is a comma-separated list of exceptions that a method can throw.

Java Methods available in Throwable class


Java types of Exception

Exceptions can be categorized in two types:

  • Unchecked Exception
  • Checked Exception

Checked Exception

If it is must to check an exception then it is called a checked exception. The program will not compile if there is a possibility of occurring checked exception in a try block and it is not handled.

The compiler ensures that if a method can throw a checked exception, directly or indirectly, then the method must explicitly deal with it. The method must either catch the exception and take the appropriate action, or pass the exception on to its caller.

Note:
Exception and all of its sub-classes (Excluding RuntimeException and its sub-classes) are checked exceptions and must be caught.

Unchecked Exception

If it is not must to check an exception then it is called an unchecked exception. The program will compile even if the unchecked exception is not handled.

If any unchecked exception occurs in a program which is not handled then the program execution will terminate at that point. But if exception is handled then program will not terminate because of exception.

Note:
  • Error and all of its subclasses are unchecked exceptions and need not be caught.
  • RunTimeException and all of its sub-classes are unchecked exceptions and need not be caught.

Java Exception Handling Construct

Java exception/error handling is managed via five keywords: try, catch, throw, throws, and finally.

The general form of an exception-handling block is:

try

{

//block of code to be monitored for errors.

}

catch(ExceptionType1 exOb1)

{

//exception handler for ExceptionType1

}

catch(ExceptionType2 exOb2)

{

//exception handler for ExceptionType1

}

.

.

.

finally

{

//block of code to be executed before try block ends

}

The code, which is to be monitored for run-time errors, is put inside a try block. The try block must be enclosed between braces even if there is only one statement in it. There can be zero or more catch statements and zero or one finally statement. Both catch and finally blocks are optional but either one catch block or one finally block is must.

The code in the try block is executed like any other Java code. If the code inside the try block executes successfully then the control goes to finally block if it is present and then the execution continues from the statement just after the end of finally block (i.e. after the end of try statement). If the finally block is not present then the execution continues from the statement just after the last catch block (i.e. after the end of try statement).

If some run-time error occurs while executing the code in try block then JVM throws an Exception/Error. This means an object of type Exception/Error or one of its sub-classes is created depending on the type of the run-time error. This is then compared with the Exception/Error types of the catch blocks in top to bottom order. If a matching catch block is found then the exception/error is handled i.e. program will not terminate. The execution continues with the first statement in the catch block. On completion of the catch block, excution continues with the statement just after the end of try statement. At the most one catch block is executed irrespective of the number of catch blocks. On completion of the catch block, excution continues with the statement just after the end of try statement. At the most one catch block is executed irrespective of the number of catch blocks.

If exception/error does not match with exception/error type of any of the catch blocks, then we say that it is not handled. The execution will immediately return from try block. The code in the finally block will be executed even if the exception/error is not handled. The exception/error will then be handled by outer try block if there is one otherwise it must be handled in the method which called the current method. The exception/error percolates up the hierarchy till it is handled or it is passed to JVM unhandled if not handled even in the main() method which is the first method from which the execution starts. The JVM then simply terminates the program and displays the exception/error details on the monitor/console.



Java Hierarchy of Exception Classes

  • Exceptions/Errors are also objects in Java.
  • Root class of all exception/error classes is the Throwable class, which is an immediate sub-class of the Object class.
  • Methods are defined in Throwable class to retrieve error message associated with the error/exception and to print the stack trace showing where the error/exception occurs.
  • There are two immediate sub classes of class Throwable:
            o Error
            o Exception
  • Sub classes of Exception have the suffix Exception.
  • Sub classes of Error have the suffix Error (normally).

Error

The sub classes of Error class are basically used for signaling abnormal system conditions like:
  • OutOfMemoryError signals that the Java VM has run out of memory and that the garbage collector is unable to claim any free memory.
  • StackOverflowError signals a stack overflow in the interpreter.

The errors are, in general, unrecoverable and should not be handled.

Exception

The sub classes of Exception class are, in general recoverable. For example, EOFException signals that a file you have opened has no more data for reading. FileNotFoundException signals that a file you want to open does not exist in the file system.

Hierarchy of common Exceptions




Java Exception Handling

An exception/error is an abnormal condition that breaks/disrupts the normal program flow. The abnormal condition occurs at run-time i.e. during code execution.

For example, a C program gets terminated when division by zero is encountered at the run-time as this is not a defined operation and results in run-time error. The other familiar example in case of C-language is that of null pointer exception, which occurs when we try to access a memory location through an un-initialized pointer. The program gets terminated in this case also.

Java has a separate construct for exception/error handling like C++. It is possible to recover from an exception/error at run-time and continue the program execution using the exception-handling construct.

A Java exception/error is an object of class Exception/Error or one of its sub-classes. JVM creates an object of class Exception/Error or one of their sub-classes whenever exception/error occurs at the run-time. The exception/error object contains details about the exception/error, which can be accessed using the public methods provided for this purpose.

Traditional Approach of Exception/Error Handling:

Use of if(), goto and return codes for propagating error back to calling method.

Advantage of Exception/Error Handling

  • Error-handling code is separated from the normal program flow to increase the

    readability and maintainability.

    We can easily say where the exception/error will be handled. Exceptions/Errors
    propagate up the call stack at runtime- first up the enclosing try blocks and then back to the calling method- until an exception handler catches them.
     
  • The location of the exception/error is known exactly as entire stack trace is available to the user. This is very helpful in debugging.
     
  • Programmer gets a chance to recover from the error/abnormal condition.
     
  • With Java, it is not must to test if an exception/error condition happens. Adding more error/exception handlers simply requires adding more catch clauses, but the original program flow need not be touched.

When Exceptions/Errors can occur?

There are many cases where abnormal conditions occur during program execution, such as:

  • The class file you want to load may be missing or in the wrong format.
  • Integer division by zero.
  • Array index is not in the valid range (i.e. from 0 to length-1).
  • The file you are trying to open may not exist.
  • The String, which you want to convert to a number, is having invalid characters so that it cannot be converted to a number.
  • You want to create an object but no more memory is available.