Runtime errors can be divided into low-level
errors that involve violating constraints, such as:
- dereference of a null pointer
- out-of-bounds array access
- divide by zero
- attempt to open a non-existent file for reading
- bad cast (e.g., casting an Object that is actually a Boolean to Integer)
and
higher-level, logical errors, such as violations of a function's precondition:
- call to Stack's "pop" method for an empty stack
- call to "factorial" function with a negative number
- call to List's nextElement method when hasMoreElements is false
Logical
errors can lead to low-level errors if they are not detected. Often, it is
better to detect them (to provide better feedback).
- When an error is detected, an exception is thrown. That is, the code that caused the error stops executing immediately, and control is transferred to the catch clause for that exception of the first enclosing try blockthat has such a clause. The try block might be in the current function (the one that caused the error), or it might be in some function that called the current function (i.e., if the current function is not prepared to handle the exception, it is "passed up" the call chain). If no currently active function is prepared to catch the exception, an error message is printed and the program stops.
- Each catch clause specifies the type of one exception, and provides a name for it (similar to the way a function header specifies the type and name of a parameter). Java exceptions are objects, so the statements in a catch clause can refer to the thrown exception object using the specified name.
- The finally clause is optional.
- In general, there can be one or more catch clauses. If there is a finally clause, there can be zero catch clauses
Question 1: Assume that function f might throw
exceptions Ex1, Ex2, or Ex3. Complete function g, outlined below, so that:
- If the call to f causes Ex1 to be thrown, g will catch that exception and print "Ex1 caught".
- If the call to f causes Ex2 to be thrown, g will catch that exception, print "Ex2 caught", and then will throw an Ex1 exception.
static void g() throws
... {
try {
f();
} catch ( ... ) {
...
} ...
}
Question 2: Consider the following function.
static void f(int k, int[] A, String S) {
int j = 1 / k;
int len = A.length + 1;
char c;
try {
c = S.charAt(0);
if (k == 10) j =
A[3];
} catch
(ArrayIndexOutOfBoundsException ex) {
System.out.println("array error");
throw new InternalError();
} catch
(ArithmeticException ex) {
System.out.println("arithmetic error");
} catch
(NullPointerException ex) {
System.out.println("null ptr");
} finally {
System.out.println("in finally clause");
}
System.out.println("after try block");
}
Part A.
Assume that variable X is an array of int that has been
initialized to be of length 3. For each of the following calls to function f,
say what (if anything) is printed by f, and what, if any, uncaught exceptions
are thrown by f.
A. f(0, X,
"hi");
B. f(10, X, "");
C. f(10, X, "bye");
D. f(10, X, null);
B. f(10, X, "");
C. f(10, X, "bye");
D. f(10, X, null);
Part B.
Why doesn't f need to have a throws clause that lists the uncaught
exceptions that it might throw?
What is printed for each
of the four runs?
1. d caught Ex1
2. c caught Ex2
b caught Ex1
3. b caught Ex3
4. a caught Ex4
execution stops due to
uncaught exception Ex1 thrown in main
Question 1:
static void g() throws Ex1, Ex3 {
try {
f();
} catch (Ex1 ex1) {
System.out.println("Ex1
caught");
} catch (Ex2 ex2) {
System.out.println("Ex2
caught");
throw new Ex1();
}
}
Question 2:
Part A.
A. f(0, X, "hi");
nothing printed
throws ArithmeticException
B. f(10, X, "");
prints "in finally clause"
throws StringIndexOutOfBoundsException
C. f(10, X, "bye");
prints "array error", "in finally
clause"
throws InternalError
D. f(10, X, null);
prints "null ptr", "in finally clause",
"after try block"
Part B.
Function f doesn't need
to have a throws clause that lists the
uncaught exceptions that
it might throw because only uncaught CHECKED
exceptions need to be
listed in a function's throws clause.
The
uncaught exceptions that
f might throw are all UNCHECKED exceptions.
Declaring your own
Exception:
You can create your own
exceptions in Java. Keep the following points in mind when writing your own exception
classes:
·
All exceptions must be a
child of Throwable.
·
If you want to write a
checked exception that is automatically enforced by the Handle or Declare Rule,
you need to extend the Exception class.
·
If you want to write a
runtime exception, you need to extend the RuntimeException class.
We can define our own
Exception class as below:
class MyException extends Exception{
}
You just need to extend
the Exception class to create your own Exception class. These are considered to
be checked exceptions. The following InsufficientFundsException class is a
user-defined exception that extends the Exception class, making it a checked exception.
An exception class is like any other class, containing useful fields and
methods.
//
File Name InsufficientFundsException.java
import java.io.*;
public class InsufficientFundsException extends Exception
{
private double amount;
public InsufficientFundsException(double amount)
{
this.amount = amount;
}
public double getAmount()
{
return amount;
}
}
To demonstrate using our
user-defined exception, the following CheckingAccount class contains a
withdraw() method that throws an InsufficientFundsException.
//
File Name CheckingAccount.java
import java.io.*;
public class CheckingAccount
{
private double balance;
private int number;
public CheckingAccount(int number)
{
this.number = number;
}
public void deposit(double amount)
{
balance += amount;
}
public void withdraw(double amount) throws
InsufficientFundsException
{
if(amount <= balance)
{
balance -= amount;
}
else
{
double needs = amount - balance;
throw new InsufficientFundsException(needs);
}
}
public double getBalance()
{
return balance;
}
public int getNumber()
{
return number;
}
}
The following BankDemo
program demonstrates invoking the deposit() and withdraw() methods of
CheckingAccount.
// File Name
BankDemo.java
public class BankDemo
{
public static void main(String [] args)
{
CheckingAccount c = new CheckingAccount(101);
System.out.println("Depositing
$500...");
c.deposit(500.00);
try
{
System.out.println("\nWithdrawing
$100...");
c.withdraw(100.00);
System.out.println("\nWithdrawing
$600...");
c.withdraw(600.00);
}catch(InsufficientFundsException
e)
{
System.out.println("Sorry, but you
are short $"
+ e.getAmount());
e.printStackTrace();
}
}
}
Compile all the above
three files and run BankDemo, this would produce the following result:
Depositing $500...
Withdrawing $100...
Withdrawing $600...
Sorry, but you are short $200.0
InsufficientFundsException
at CheckingAccount.withdraw(CheckingAccount.java:25)
at BankDemo.main(BankDemo.java:13)
·
Exception can arise from different kind of
situations such as wrong data entered by user, hardware failure, network
connection failure, Database server down etc. In this section, we will learn
how exceptions are handled in java.
·
Post a Comment