Exceptions
- Look at
MotivateExceptions.java
.- This is a chain of simple methods that processes a data file.
- What should happen if a problem is detected at the very end of this chain?
- Imagine trying to pass error information all the way up that call stack.
- Each method would have to have an
if
statement checking for success. - Might even need a complex return type to store different error conditions.
- What should a constructor do if there is a problem? (Remember, it doesn’t have a typical return value.)
- Solution: Exceptions.
- An exception is simply an object that describes a problem
- When a problem is detected, you instantiate an exception object and
throw
it. - This object will propagate up the call stack until either:
- Somebody
catch
es it and handles it, or - It gets passed up by
main
and the program crashes with a stack trace.
- Somebody
- This allows you to automatically pass problems up to the level where they can actually be handled.
- And not have to explicitly touch them along the way.
-
Look at
MotivateExceptions2.java
- Exceptions are organized into a hierarchy
- The hierarchy allows you too look for problems at a variety of levels
- e.g., do you want to see any errors at all, or just those involved with I/O?
- e.g., do you want to see an I/O related errors, or just FileNotFound.
- Think about it as a hunting license. Do you want a license for rabbit, mammals, or any animal?
Checked vs. Unchecked exceptions
- In it’s motherly attempt to be helpful, Java generally requires you acknowledge any potential exceptions by either
catch
ing them, or- putting a
throws
statement in the method signature.
- The
throws
clause is how the compiler knows to nag anybody using the method. - However: Some exceptions (e.g.,
NullPointerException
orIndexOutOfBounds
exceptions) could (but shouldn’t) happen at any time.- Effectively every method would need a
catch
orthrows
for these exceptions. - Therefore, these exceptions are excluded from the “acknowledge” rule.
- Effectively every method would need a
- As a result, Java has two types of exceptions: Checked and Unchecked
- Checked exceptions require acknowledgement (
catch
orthrows
) - Unchecked exceptions do not.
- Checked exceptions require acknowledgement (
- This is implemented using inheritance:
- Any Exception that is a descendant of the
RuntimeException
class is unchecked. - All other exceptions are checked.
- Any Exception that is a descendant of the
- Notice that
Exception
implements theThrowable
interface. - The other class that implements
Throwable
isError
.- Errors are like exceptions; but are generally not recoverable.
- They typically represent problems with the class loader or JVM that you can’t fix as the program is running (e.g., running out of memory)
Making your own exceptions
- Simply create a class that inherits from either
Exception
(if you want it checked) orRuntimeException
(if you don’t).Exception
provides aString
instance variable.- Feel free to add your own additional instance variables if desired.
- See
InvoiceWithCustomException.java
- Look at my
Date163
solution. Notice- Constructor throws
IllegalArgumentException
if date can’t be created. - I could have written a custom exception if I wanted more nuance in the cause of the problem.
- Notice the catch and re-throw.
- Notice that
NumberFormatException
is a subclass ofIllegalArgumentException
, so the catch and re-throw is technically unnecessary (except that I wanted to customize the error message).
- Constructor throws
Misc.
- Remember: A method stops executing when it hits a
throws
statement. (The following lines of code don’t execute.) - If you have “clean up” code that should always run, you can put it in a
finally
block. - Avoid using exceptions when a simple
if
statement could avoid the problem. For example,if (x < array.length>)
is better than plowing ahead and catching theArrayIndexOutOfBoundsException
.- Likewise, I prefer checking to see if a file exists before trying to open it.
- However, since files can get deleted while a program is running, you still need the try/catch block.