Download Exceptions

Document related concepts
no text concepts found
Transcript
Exceptions
• You need to understand classes and inheritance before
you can understand what an exception is and appreciate
what happens when an exception occurs.
• An exception usually signals an error and so called
because errors in your programs are bound to be the
exception rather than the rule – by definition!
• An exception can also signal some particularly unusual
event in your program that deserves special attention.
Exceptions
tMyn
1
• If you try to deal with the myriad and often highly unusual
error conditions that might arise in the midst of the code
that deals with the normal operation of the program, your
program structure will soon become very complicated
and difficult to understand.
• One major benefit of having an error signaled by an
exception is that it separates the code that deals with
errors from the code that is executed when things are
moving along smoothly.
• Another positive aspect of exceptions is that they provide
a way of enforcing a response to particular errors.
• With many kinds of exceptions, you must include code in
your program to deal with them.
Exceptions
tMyn
2
• One important idea to grasp is that not all errors in your
programs need to be signaled by exceptions.
• Exceptions should be reserved for the unusual or
catastrophic situations that can arise.
• A user entering incorrect input to your program for
instance is a normal event and should be handled
without recourse to exceptions.
• The reason for this is that dealing with exceptions
involves quite a lot of processing overhead, so if your
program is handling exceptions a lot of the time it will be
a lot slower than it needs to be.
Exceptions
tMyn
3
• An exception in Java is an object that is created when an
abnormal situation arises in your program.
• This exception object has fields that store information
about the nature of the problem.
• The exception is said to be thrown – that is, the object
identifying the exceptional circumstance is tossed as an
argument to a specific piece of program code that has
been written specifically to deal with that kind of problem.
• The code receiving the exception object as a parameter
is said to catch it.
Exceptions
tMyn
4
• The situations that cause exceptions are quite diverse,
but they fall into four broad categories:
1. Code or data errors: For example, you attempt an
invalid cast of an object, you try to use an array index
that is outside the limits for the array, or an integer
arithmetic expression has a zero divisor.
2. Standard method exceptions: For example, if you use
the substring() method in the String class, it can
throw a StringIndexOutOfBoundsException
exception.
Exceptions
tMyn
5
3. Throwing your own exceptions.
4. Java errors. These can be due to errors in executing
Java Virtual Machine, which runs your compiled
program, but usually arise as a consequence of an error
in your program.
Exceptions
tMyn
6
• So we can conclude that exception handling is designed
to process synchronous errors, which occur when a
statement executes. Common examples are out-ofrange array indices, arithmetic overflow (a value outside
the representable range of values), division by zero,
invalid method parameters, thread interruption and
unsuccessful memory allocation.
• Exception handling is not designed to process problems
associated with asynchronous events. These are disk
I/O completions, network message arrivals, mouse clicks
and keystrokes, which occur in parallel with, and
independent of, the program’s flow of control.
Exceptions
tMyn
7
• An exception is always an object of some derived class
of the standard class Throwable.
• This is true for exceptions that you define and throw
yourself, as well as the standard exceptions that arise
due to errors in your code.
• It is also true for exceptions that are thrown by methods
in one or another of the standard packages.
• Two direct derived classes of the class Throwable – the
class Error and the class Exception – cover all the
standard exceptions.
• Both these classes themselves have derived classes
that identify specific exception conditions, Figure 1:
Exceptions
tMyn
8
Throwable
Object
Error
Exception
…
…
IOException
EOFException
FileNotFoundException
RuntimeException
…
Figure 1. Part of the exception class hierarchy.
Exceptions
tMyn
9
• For almost all the exceptions that are represented by
derived classes of the Exception class, you must
include code in your program to deal with them if your
code may cause them to be thrown.
• If a method in your program has the potential to generate
an exception of a type that has Exception as a base
class, you must either handle the exception within the
method or indicate that your method may throw such an
exception. If you don’t, your program will not compile.
• One group of derived classes of Exception that is
exempted from this is comprised of those derived from
RuntimeException.
Exceptions
tMyn
10
• The reason that RuntimeException exceptions are
treated differently, and that the compiler allows you to
ignore them, is that they generally arise because of
serious errors in your code.
• In most cases you can do little to recover the situation.
• The derived classes of RuntimeException defined in
the standard package java.lang are:
• ArithmeticException,
IndexOutOfBoundsException,
NegativeArraySizeException,
NullPointerException, ArrayStoreException,
ClassCastException,
Exceptions
tMyn
11
IllegalArgumentException,
SecurityException,
IllegalMonitorStateException,
IllegalStateException,
UnsupportedOperationException.
Exceptions
tMyn
12
• The exceptions that are defined by the Error class and
its derived classes are characterized by the fact that they
all represent conditions that you aren’t expected to do
anything about, so you aren’t expected to catch them.
• Error has three direct derived classes: ThreadDeath,
LinkageError and VirtualMachineError.
• The Java exception hierarchy contains hundreds of
classes.
• You can extend this hierarchy with your own exception
classes.
Exceptions
tMyn
13
• Let’s start with a simple example where we have no
exception handler. This program attempts to read
beyond the bounds of an array:
Exceptions
tMyn
14
package exception;
public class Main
{
public static void main(String[] args)
{
int[] numbers={1, 2, 3};
for(int i=0; i<=3; i++)
System.out.println(numbers[i]);
}
}
Exceptions
tMyn
15
run:
1
2
3
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at exception.Main.main(Main.java:11)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)
Exceptions
tMyn
16
• The program crashes when it tries to read the element at
numbers[3], and displays an error message.
• This message indicates that an exception occurred, and
it gives some information about it.
• An exception is an object that is generated in memory as
the result of an error or an unexpected event.
• When an exception is generated, it is said to have been
thrown.
• Unless an exception is detected by the application and
dealt with, it causes the application to halt (as what
happened in the preceding example).
Exceptions
tMyn
17
• In general, if your program does not catch an exception,
then it will be caught by the JVM.
• The trouble is that the JVM’s default exception handler
terminates execution and displays a stack trace error
message.
• So when the array index error occurred, execution was
halted, and the following error message was displayed:
Exception in thread "main"
java.lang.ArrayIndexOutOfBoundsExcep
tion: 3
at exception.Main.main(Main.java:11)
Exceptions
tMyn
18
• While such a message is useful for you while debugging,
it would not be something that you would want others to
see, to say the least!
• This is why it is important for your program to handle
exceptions itself, rather than rely upon the JVM.
Exceptions
tMyn
19
• The next example uses exception handling to process
any ArithmeticExceptions and
InputMismatchExceptions that may arise.
• Taken from the documents:
public int nextInt(int radix)
Scans the next token of the input as an int. This method
will throw InputMismatchException if the next token
cannot be translated into a valid int value as described
below. If the translation is successful, the scanner
advances past the input that matched.
Exceptions
tMyn
20
package TimoSoft;
public class SomeMath
{
public SomeMath()
{
System.out.println("SomeMath constructor.");
}
public int quotient(int numerator, int denominator)
throws ArithmeticException
{
return numerator/denominator;
}
See the
}
explanation
next page!
Exceptions
tMyn
21
• The method declaration from the previous page has a
throws clause.
• A throws clause specifies the exceptions the method
throws.
• This clause appears after the method’s parameter list
and before the method’s body.
• It contains a comma-separated list of the exceptions that
the method will throw if various problems occur.
• Such exceptions may be thrown by statements in the
method’s body or by methods called from the body.
• A method can throw exceptions of the classes listed in its
throws clause or of their derived classes.
Exceptions
tMyn
22
• The throws clause in the method quotient() indicates
to the rest of the program that this method may throw an
ArithmeticException exception.
Exceptions
tMyn
23
Error-prevention tip:
• Read the online API documentation for a method before
using that method in a program. The documentation
specifies the exceptions thrown by the method (if any)
and indicates reasons why such exceptions may occur.
Next, read the online API documentation for the specified
exception classes. The documentation for an exception
class typically contains potential reasons that such
exceptions occur. Finally, provide for handling those
exceptions in your program.
Exceptions
tMyn
24
package TimoSoft;
import java.util.Scanner;
import java.util.InputMismatchException;
public class Test
{
public static void main(String[] args)
{
SomeMath first=new SomeMath();
Scanner keyb1=new Scanner(System.in);
boolean continueLoop=true;
do
{
try
{
System.out.print("Please enter an integer numerator: ");
int newNumerator=keyb1.nextInt();
Exceptions
tMyn
25
System.out.print("Please enter an integer denominator: ");
int newDenominator=keyb1.nextInt();
int result=first.quotient(newNumerator, newDenominator);
System.out.println("The result was: "+result+".");
continueLoop=false;
}
catch(InputMismatchException misMatch)
{
System.err.println("Exception took place: "+misMatch);
keyb1.nextLine();
System.out.println("You must enter integers, try again.");
See the
explanation }
next page! catch(ArithmeticException ariExc)
{
System.err.println("Exception took place: "+ariExc);
System.out.println("Zero is an invalid denominator, try again.");
}
}while(continueLoop);
}
}
Exceptions
tMyn
26
• From the previous page: Because an
InputMismatchException has occurred, the call to
method nextInt() never successfully read in the
user’s data – so we read that input with a call to method
nextLine(). We do not do anything with the input at
this point, because we know it is invalid.
Exceptions
tMyn
27
run:
SomeMath constructor.
Please enter an integer numerator: 100
Please enter an integer denominator: 3
The result was: 33.
BUILD SUCCESSFUL (total time: 8 seconds)
Exceptions
tMyn
28
run:
SomeMath constructor.
Please enter an integer numerator: 234
Please enter an integer denominator: 0
Exception took place: java.lang.ArithmeticException: / by zero
Zero is an invalid denominator, try again.
Please enter an integer numerator: 234
Please enter an integer denominator: 4
The result was: 58.
BUILD SUCCESSFUL (total time: 25 seconds)
Exceptions
tMyn
29
run:
SomeMath constructor.
Please enter an integer numerator: hello
Exception took place: java.util.InputMismatchException
You must enter integers, try again.
Please enter an integer numerator: 456
Please enter an integer denominator: 88
The result was: 5.
BUILD SUCCESSFUL (total time: 21 seconds)
Exceptions
tMyn
30
From the preceding example:
• Class InputMismatchException is imported but
class ArithmeticException does not need to
because it is in package java.lang.
Enclosing code in a try block:
• try block encloses the code that might throw an
exception and the code that should not execute if an
exception occurs. That is to say: if an exception occurs,
the remaining code in the try block will be skipped.
Exceptions
tMyn
31
• You need to take care when adding try blocks to
existing code.
• A try block is no different to any other block between
braces when it comes to variable scope.
• Variables declared in a try block are available only until
the closing brace for the block.
• It is easy to enclose the declaration of a variable in a
try block, and, in doing so, inadvertently limit the scope
of the variable and cause compiler errors.
Exceptions
tMyn
32
• Catching exceptions:
• The try block in the preceding example is followed by
two catch blocks – one that handles an
InputMismatchException and one that handles an
ArithmeticException.
• A catch block (also called a catch clause or exception
handler) catches (receives) and handles an exception.
• At least one catch block or a finally block
(discussed later) must immediately follow the try block.
• Each catch block specifies in parentheses an exception
parameter that identifies the exception type the handler
can process.
Exceptions
tMyn
33
• The try and catch blocks are bonded together.
• You must not separate them by putting statements
between the two blocks.
• If no exception is thrown, then a try block ends
normally, and all of its catch statements are bypassed.
• Execution resumes with the first statement following the
last catch.
Exceptions
tMyn
34
• When an exception occurs in a try block, the catch
block that executes is the first one whose type matches
the type of the exception that occurred – i.e., the type in
the catch block matches the thrown exception type
exactly or is a base class of it.
• The exception parameter’s name enables the catch
block to interact with a caught exception object – e.g., to
implicitly invoke the caught exception’s toString()
method, which displays basic information about the
exception.
• Notice that the System.err (standard error stream)
object is used to output error messages.
Exceptions
tMyn
35
• If an exception occurs in a try block, the try block
terminates immediately and program control transfers to
the first of the following catch blocks in which the
exception parameter’s type matches the thrown
exception’s type.
• After the exception is handled, program control does not
return to the throw point, because the try block has
expired (and its local variables have been lost).
• Rather, control resumes after the last catch block.
• This is known as the termination model of exception
handling.
Exceptions
tMyn
36
• If you do not like to use the System.err (standard error
stream) object is to output error messages, you can use
standard output object System.out as previously.
• Class Throwable’s getMessage() method returns the
descriptive string stored in an exception:
• public String getMessage()
Returns the detail message string of
this throwable.
Returns: the detail message string of
this Throwable instance (which may be
null).
Exceptions
tMyn
37
• From the class Object is inherited the method
getClass():
• public final Class getClass()
Returns the runtime class of an object.
That Class object is the object that is
locked by static synchronized methods of
the represented class.
Returns: the object of type Class that
represents the runtime class of the
object.
Exceptions
tMyn
38
package TimoSoft;
public class SomeMath
{
public SomeMath()
{
System.out.println("SomeMath constructor.");
}
public int quotient(int numerator, int denominator)
throws ArithmeticException
{
return numerator/denominator;
}
}
Exceptions
tMyn
39
package TimoSoft;
import java.util.Scanner;
import java.util.InputMismatchException;
public class Test
{
public static void main(String[] args)
{
SomeMath first=new SomeMath();
Scanner keyb1=new Scanner(System.in);
boolean continueLoop=true;
do
{
try
{
System.out.print("Please enter an integer numerator: ");
int newNumerator=keyb1.nextInt();
Exceptions
tMyn
40
System.out.print("Please enter an integer denominator: ");
int newDenominator=keyb1.nextInt();
int result=first.quotient(newNumerator, newDenominator);
System.out.println("The result was: "+result+".");
continueLoop=false;
}
catch(InputMismatchException misMatch)
{
System.out.println("Exception took place: "+
misMatch.getClass());
keyb1.nextLine();
System.out.println("You must enter integers, try again.");
}
Exceptions
tMyn
41
catch(ArithmeticException ariExc)
{
System.out.println("Exception took place: "+ariExc.getClass()+
": "+ariExc.getMessage());
System.out.println("Zero is an invalid denominator, try again.");
}
}while(continueLoop);
}
}
Exceptions
tMyn
42
run:
SomeMath constructor.
Please enter an integer numerator: 234
Please enter an integer denominator: 0
Exception took place: class java.lang.ArithmeticException: / by zero
Zero is an invalid denominator, try again.
Please enter an integer numerator: 234
Please enter an integer denominator: 4
The result was: 58.
BUILD SUCCESSFUL (total time: 33 seconds)
Exceptions
tMyn
43
run:
SomeMath constructor.
Please enter an integer numerator: hello
Exception took place: class java.util.InputMismatchException
You must enter integers, try again.
Please enter an integer numerator: 982
Please enter an integer denominator: 4
The result was: 245.
BUILD SUCCESSFUL (total time: 19 seconds)
Exceptions
tMyn
44
• An uncaught exception is an one for which there are no
matching catch blocks.
• If a program has multiple threads, an uncaught exception
will terminate only the thread where the exception
occurred. Certain threads may rely on others, and if one
thread terminates due to an uncaught exception, there
may be adverse effects to the rest of the programs.
• The discussion on threads is beyond this module.
Exceptions
tMyn
45
• Java distinguishes between checked exceptions and
unchecked exceptions.
• This distinction is important, because the Java compiler
enforces a catch-or-declare requirement for checked
exceptions (catch or specify requirement).
• An exception’s type determines whether it is checked or
unchecked.
• All exception types that are direct or indirect derived
classes of class RuntimeException are unchecked
exceptions.
• All classes that inherit from class Exception but not
class RuntimeException are considered to be
checked exceptions.
Exceptions
tMyn
46
• Classes that inherit from class Error are considered to
be unchecked.
• The compiler checks each method call and method
declaration to determine whether the method throws
checked exceptions.
• If so, the compiler verifies that the checked exception is
caught or is declared in a throws clause.
• The throws clause specifies the exceptions a method
throws. Such exceptions are not caught in the method’s
body.
Exceptions
tMyn
47
• To satisfy the catch part of the catch-or-declare
requirement, the code that generates the exception must
be wrapped in a try block and must provide a catch
handler for the checked-exception type (or one of its
base class types).
• To satisfy the declare part of the catch-or-declare
requirement, the method containing the code that
generates the exception must provide a throws clause
containing the checked-exception type after its
parameter list and before its method body.
• If the catch-or-declare requirement is not satisfied, the
compiler will issue an error message indicating that the
exception must be caught or declared.
Exceptions
tMyn
48
• Unlike checked exceptions, the Java compiler does not
check the code to determine whether an unchecked
exception is caught or declared.
Exceptions
tMyn
49
• The finally block, sometimes referred to as the
finally clause, is optional.
• If it is present, it’s placed after the last catch block.
• Java guarantees that the finally block will execute
whether or not an exception is thrown in the
corresponding try block.
• Because a finally block almost always executes, it
typically contains resource-release code.
Exceptions
tMyn
50
• When faced with choosing the type of exception to throw,
you can either use one written by someone else – the
Java platform provides a lot of exception classes you
can use – or you can write one of your own.
• Typically you can probably use someone else’s.
• Your exception classes must always have Throwable
as a base class; otherwise, they will not define an
exception.
• Although you can derive them from any of the standard
exception classes, your best policy is to derive them
from the Exception class.
Exceptions
tMyn
51
• This will allow the compiler to keep track of where such
exceptions are thrown in your program and check that
they are either caught or declared as thrown in a
method.
• If you use RuntimeException or one of its derived
classes, the compiler checking for catch blocks of your
exception class will be suppressed.
• By convention, your exception class should include a
default constructor and a constructor that accepts a
String object as an argument.
• Next example uses a new exception class:
Exceptions
tMyn
52
package TimoSoft;
public class NegativeStartingBalanceException extends Exception
{
public NegativeStartingBalanceException(double amount)
{
super("Error: Negative starting balance: "+amount);
}
}
Exceptions
tMyn
53
package TimoSoft;
public class BankAccount
{
protected double balance;
public BankAccount(double startBalance)
throws NegativeStartingBalanceException
{
if(startBalance < 0)
throw new NegativeStartingBalanceException(startBalance);
balance = startBalance;
}
public void deposit(double amount)
{
balance += amount;
}
Exceptions
tMyn
54
public void withdraw(double amount)
{
balance -= amount;
}
public void setBalance(double b)
{
balance = b;
}
public double getBalance()
{
return balance;
}
}
Exceptions
tMyn
55
package TimoSoft;
public class Test
{
public static void main(String[] args)
{
try
{
BankAccount myAccount =new BankAccount(-400.0);
}
catch(NegativeStartingBalanceException e)
{
System.out.println(e.getMessage());
System.out.println(e.getClass());
}
}
}
Exceptions
tMyn
56
run:
Error: Negative starting balance: -400.0
class TimoSoft.NegativeStartingBalanceException
BUILD SUCCESSFUL (total time: 1 second)
Exceptions
tMyn
57