Working with methods that throw exceptions

advertisement
Overview
Exceptions
Why Exceptions?
• Exceptions allow the programmer to
treat error conditions outside the
main logic flow
• Most programming languages (without
exceptions) handle errors by passing
return codes as error indicators
• Why Exceptions?
• Working with methods that throw
exceptions
• The try-catch-finally block
• The class Exception and its subclasses
• Checked vs Unchecked Exceptions
• Defining your own Exceptions
What’s an Exception
• A signal that indicates an
exceptional condition (something
unexpected) has happened in your
program
• To throw an exception is to signal
that an exceptional condition has
occurred
• To catch an exception is to handle
the exception - to take whatever
action is necessary
– sometimes you can’t do anything
Working with methods
that throw exceptions
Exception Example 1
the FileInputStream class
constructor
public FileInputStream (String s) throws FileNotFoundException;
String s = “myfile.dat”;
FileInputStream fis = new FileInputStream (s);
will not compile
unless…
we deal with the possibility
of an Exception
Exception Example 2
the Thread class
may throw
exception
try {
FileInputStream fis = new FileInputStream (s);
}
catch (FileNotFoundException e) { }
Thread static method
public static void sleep (long millis)
throws InterruptedException;
Thread.sleep(1000);
will not compile
unless….
Exception Example 2
[catching the exception]
Thread static method
public static void sleep (long millis)
throws InterruptedException;
try {
Thread.sleep(1000);
}
catch (InterruptedException e) { }
Handling Exceptions...
C:\class\Programs\Exceptions\ExceptTest.java:6:
Exception java.io.FileNotFoundException must be
caught, or it must be declared in the throws
clause of this method.
• Catch the exception in our method
OR
• List the exception in our own method
header
quick way to play with code
that throws exceptions
Exception Example 2
[catching the exception]
Thread static method
public static void sleep (long millis)
throws InterruptedException;
OR .. can catch a superclass
of the Exception class
try {
Thread.sleep(1000);
}
catch (Exception e) { }
Throwable
Exception
InterruptedException
class ThreadSleepTest {
public static void main (String [] args)
throws InterruptedException {
}
for (int i=0; i< 10; i++) {
if ( i == 5) Thread.sleep(1000);
System.out.print(i + ".. ");
}
>java ThreadSleepTest
0.. 1.. 2.. 3.. 4.. 5.. 6.. 7.. 8.. 9..
one second pause
try-catch
the complete story
class ThreadSleepTest2 {
public static void main (String [ ] args) {
try {
for (int i=0; i< 10; i++) {
if ( i == 5) Thread.sleep(2000);
System.out.print(i + ".. ");
}
}
catch (InterruptedException e) {
}
try {
// code that might
// throw an exception
} catch (ExceptionType variable) {
// handle the exception if thrown
} finally {
// .. always do this
}
}
// assume t is a thread object
try {
t.sleep(1000);
} catch (InterruptedException e) {
System.out.println(“an exceptions was thrown”);
} finally {
System.out.println(“finally”);
}
Used for
cleanup close files,
release
resources...
Try..Catch..Finally Combo
Rules
• You cannot use try alone
• A try block requires catch or finally
or both
• A catch or finally block requires a try
block
• The finally block is always executed
as part of the Java control flow
– even if you use a return or break to
avoid a finally block
Catching multiple exceptions
• You may have multiple catch blocks
associated with one try block
try {
someObject.test();
anotherObject.foo();
} catch (InterruptedException e1) {
// do something with e1
} catch (IOException e2) {
// do something with e2
} catch (NullPointerException e3) {
// do something with e3
}
You must use a
different parameter
name. All are in the
same scope
An exception is
handled by the first
catch block with a
type match
The Exception Hierarchy
The Exception Hierarchy
public String getMessage( )
public void printStackTrace ( )
A Java exception is an object
that is an instance of some
subclass of Throwable
includes a String
message that is
inherited by all
subclasses
Throwable
Error
Errors are exceptions that
result from system problems
(e.g. Java Virtual Machine)
Errors are almost always
unrecoverable - should not be
caught
The Exception Hierarchy
Throwable
Exception
Conditions that may be
caught and handled
Error
A user defined exception
should subclass Exception
Often recoverable
Exception
UserDefinedException
Using Methods from Throwable
try {
t.sleep(1000);
Throwable
} catch (InterruptedException e) {
System.out.println(e.getMessage() );
e.printStackTrace();
} finally {
System.out.println(“finally”);
}
What Exceptions Must be
Caught?
Exception
InterruptedException
Checked Exceptions
those that the compiler
checks that you’ve handled
UnChecked Exceptions
Throwable
Throwable
unchecked
errors
unchecked
exceptions
Error
Error
Exception
RuntimeException
AnyOtherSubclass
Checked
exceptions
Must be caught!!
Unchecked
Exceptions
Exception
RuntimeException
ArithmeticException
IndexOutOfBoundsException
The programmer is not required to catch these
-- although they may crash your program
public void foo (int k ) {
foo (0);
public void foo (int k ) {
int j=1;
foo (0);
int j=1;
System.out.println( j / k );
}
try { System.out.println( j / k );
}
catch (ArithmeticException e) {
System.out.println(“Some idiot passed a zero”);
}
Unchecked Exception is
thrown if k = 0
Program aborts with message:
Program does not abort
Java.lang ArithmeticException: / by Zero
}
public void foo (int k ) {
Error
int j=1;
not a good class
name - all
exceptions occur
at runtime
Exception
if (k==0) {
System.out.println(“Some idiot passed a zero”);
}
else {
System.out.println( j / k );
}
Program does not abort
}
Exception Subclasses
Throwable
foo (0);
RuntimeException
ArithmeticException
IndexOutOfBoundsException
NegativeArraySizeException
AWTException
Must be caught in
try..catch block or
passed on….
InterruptedException
Exceptions not used...
IOException
class ExceptionPropagateTest {
public static void main (String args [ ] ) {
Exceptions Travel Up the
Call Stack
foo ();
}
public static void foo () {
bar ();
}
public static void bar () {
int j=1, k=0;
program
aborts
main
foo
bar
System.out.println( j / k );
}
}
exception
looking for a
catch block
When Checked Exceptions
get Thrown
class ExceptionPropagateTest {
public static void main (String args [ ] ) {
foo ();
}
public static void foo () {
An exception may be
try { bar (); }
caught anywhere in
catch (ArithmeticException e) {
the calling stack
System.out.println("Caught it in foo ");
}
}
Programmer Options
This program terminates normally
public static void bar () {
int j=1, k=0;
System.out.println( j / k );
}
}
NOTE: the compiler does not
require you to catch this
unchecked exception
(catch or pass the buck)
Option 1 for Checked Exceptions
Option 2 for Checked Exceptions
Option 1. - catch it!
may throw a
public void foo() {
checked exception
try {
t.sleep(1000);
}
catch (InterruptedException e) {
System.out.println(“can’t sleep”);
}
}
• Option 2. - explicitly rethrow the exception
void foo() throws InterruptedException {
try {
t.sleep(1000);
}
catch (InterruptedException e) {
// do something locally then.
count++;
throw(e);
now the caller of
} }
foo( ) must beware!!
void foo() throws InterruptedException
Option 3 for Checked Exceptions
Option 3. - pass the buck - implicitly
void bar () {
// some code
try {
foo ();
}
catch (InterruptedException e) {
System.out.println(“oops! ”);
}
// some more code
}
void foo() throws InterruptedException {
t.sleep(1000);
}
the compiler knows
that some method will
handle the exception!!
any caller of foo( )
must either catch or
pass the buck!
Throwing Unchecked Exceptions
• Unchecked Exceptions
– A method may throw any unchecked
exception
– No requirement to declare anything in
the method declaration
Throwing Exceptions
void foo() {
if (…)
throw new ArithmeticException ();
if (…)
throw new IndexOutOfBoundsException ();
}
Throwing Checked
Exceptions
• Checked Exceptions
– A method may throw any checked
exception as long as either:
• the exception class is declared in the method
throws clause
• a superclass of the exception class is declared in
the method throws clause
void foo (int i) throws Exception {
if (i == 0)
throw new IOException();
}
Exception
OR… you may declare a
superclass of the exception
type you throw
IOException
not good practice but
allowed by Java’s rules for
subclass substitution
void foo (int i) throws IOException {
if (i == 0)
throw new IOException();
}
you must declare the type
of any checked exception
you throw … OR
throw - catch parameter matching
void bar () {
try {
foo(4);
}
catch (IOException e) {
}
}
the catch clause
MUST specify a
compatible type
with throws
header
void foo (int i) throws IOException {
if (i == 0)
throw new IOException();
}
throw - catch parameter matching
throw - catch parameter matching
void bar () {
try {
foo(4);
}
catch (Exception e) {
}
}
this will compile
but is poor
programming
practice!
void bar () {
compiler will
try {
not allow this!
foo(4);
}
catch (IOException e) {
}
}
void foo (int i) throws IOException {
if (i == 0)
throw new IOException();
}
void foo (int i) throws Exception {
if (i == 0)
throw new IOException();
}
Compiler: Exception java.lang.Exception must be caught
Multiple Catch Blocks..
Multiple Catch Blocks..GOTCHA!
try {
checked in order
until match is found!
someObject.test();
anotherObject.foo();
} catch (InterruptedException e1) {
// do something with e1
} catch (IOException e2) {
// do something with e2
try {
someObject.test();
anotherObject.foo();
} catch (Exception e1) {
// do something with e1
} catch (IOException e2) {
// do something with e2
} catch (NullPointerException e3) {
} catch (NullPointerException e3) {
// do something with e3
// do something with e3
}
}
Multiple Catch Blocks
try {
someObject.test();
list most specific
anotherObject.foo();
Exceptions first
} catch (IOException e1) {
// do something with e1
} catch (NullPointerException e2) {
// do something with e2
} catch (Exception e3) {
// do something with e3
}
matches ALL
Exceptions and
subclasses of
Exception
list most general
Exceptions last
Creating Your Own
Exception Classes
Creating Your Own Exception Class
• extend the class Exception
• take advantage of the Exception class
constructor
throwing your exception
You throw an exception by combining the
keyword throw with object creation:
– Exception (String s)
• the string can be retrieved by sending
getMessage() to the exception object
throw new MyException(“MyException ZZ”);
public class MyException extends Exception {
// constructor
public MyException (String s) {
super(s); // calls the superclass constructor
}
}
public class A {
public static void main(String args []) {
A myObj = new A();
try {
myObj.test();
} catch (Exception e) {
System.out.println(e.getMessage() );
}
}
void test () throws MyException
{
throw new MyException("hey");
}
}
this can be a very
specific message
hey
How should you handle
Exceptions?
class MyException extends Exception {
MyException (String s) {
super(s); // calls the superclass constructor
}
you must call the superclass’ constructor
}
FileInputStream in =
new
FileInputStream(“employee.dat”);
do we need to
catch exceptions
here?
Ask the compiler,
AND/OR
Look up the method
declarations
public FileInputStream (String name) throws
FileNotFoundException;
requires a design decision how to
handle if NOT a subclass of
RuntimeException
Options
•
•
•
•
•
Do nothing .. ignore it
Print a message and bail out
Pass the buck
Get some new information and retry
Pass an application-specific exception
back to the caller
Do Nothing
try {
FileInputStream in =
new FileInputStream(“employee.dat”);
} catch (FileNotFoundException e) {}
compiler is happy but
programmer may spend hours
trying to debug the program
Print and Bail
try {
Print and Rethrow
try {
FileInputStream in =
new FileInputStream(“employee.dat”);
}
FileInputStream in =
new FileInputStream(“employee.dat”);
}
catch (FileNotFoundException e) {
catch (FileNotFoundException e) {
System.out.println (“can’t find employee.dat file”);
System.out.println (“can’t find
employee.dat file”);
System.exit(1);
}
throw e;
}
“print a message and bail out”
Pass the Buck
“print a message and let the
calling method handle it”
Retry Option -- put try/catch in a loop
int tries = 0;
public void foo ()
throws FileNotFoundException {
FileInputStream in =
new FileInputStream(“employee.dat”);
while (tries < 3) {
try {
String s = getNameFromUser();
}
FileInputStream in =
new FileInputStream(“employee.dat”);
} catch (FileNotFoundException e) {
tries++;
}
} // end while loop
Application Specific
Exceptions
• Components by “contract”
i will do x if the parameters you send
me conform to what i expect
what if they don’t?
Throw Application-Specific Exception
boolean success = false;
int tries = 0;
while (tries < 3) {
try {
String s = getNameFromUser();
DataInputStream in = new DataInputStream (new
FileInputStream(s));
success = true;
} catch (FileNotFoundException e) {
tries++;
}
} // end while
if (!success)
throw new UserIsJerkException (“user can’t supply
a correct file name”);
Application Specific
Exceptions
• Components by “contract”
i will do x if the parameters you send
me conform to what i expect
throw application-specific exception
Download