Lecture 07 Exception Handling
Lecture 07 Exception Handling
Handling
SE116: Introduction to Programming II
Previously on SE116
● We have covered the use of run-time polymorphism, abstract classses, and interfaces.
● Polymorphism refers to binding of the corresponding memory addresses of the same named methods to the code where they are called.
● There are two kinds of polymorphism:
● Compile-time polymorphism (also referred as early binding or static binding)
● In use for ‘overloaded methods’
● The compiler is able to separate the overloaded methods since their signatures are different.
● Run-time polymorphism (also referred as late binding or dynamic binding)
● In use for ‘overridden methods’
● If the programming languge supports the run-tiime polymorphism, the compiler ignores binding of an overridden method called via a superclass reference.
● Run-time polymorphism provides the programming language with binding an overridden method on a subclass object where the method is called via a
superclass reference.
● The keyword ‘abstract’ in Java is used for a method and/or a class.
● An abstract method has no body definition. An abstract method can only be a member of an abstract class.
● An abstract class contains constructor at least. An abstract class can contain data members and/or defined methods and/or abstract methods.
● If a class is not abstract, then it is a concrete class.
● An abstract class can not be used to instantiate an object. An abstract class can be used as a superclass in an inheritance hiearchy and can be used to define a variable
that would refer to a concrete subclass object in that hiearchy.
● The keyword ‘interface’ in Java is used to create data types diferent than classes.
● An interface is used to declare abstract method(s).
● An interface is not a class. Therefore, an interface can not be used to instantiate an object. A class can realize an interface by implementing the body definitions of the
abstract methods of that interface.
● If a concrete class ‘implements’ an interface, the class must override all the abstract methods of the interface.
● An interface can extend another interface. A class can implement multiple interfaces.
● An interface can also contain variables specifed as ‘public final static’.
● Checkpoint: Using interface vs using abstract class?
Previously on SE116
● What are the main features of an Object Oriented Programming Language?
○ An object oriented programming language should provide the following features (at least):
■ encapsulation,
■ inheritance,
■ polymorphism (run-time polymorphism is meant here).
● So, we are done with the main features. From now on, let’s dissect another feature
supported by Java programming language: ‘exception handling’.
Introduction
● Definition: An exception is an event, which occurs during the execution of a
program, that disrupts the normal flow of the program's instructions.
● Compilation errors can be detected by the compiler at compilation time.
● Run-time (execution) errors happen because of unexpected turn of events.
● It is not always possible to foresee these runtime errors, but we at least have
an idea about where they might appear.
● However, how can we handle them as the program is in execution?
● Remember the call stack.
Introduction
● The entry to every application is the main function.
● This function calls other functions, and other functions call others.
● There can only be a single function executing in a single thread.
● Every time a function is called, it is placed in a “call stack.”
● Stacks are a basic data structure that you will learn next year. For now, you
should know that they are simply a list.
○ We push a value (in this case the function) to the stack; that is, we add it to the list.
○ We pop a value from the stack; that is we get the value AND remove it from the list.
○ Stacks are first in last out; if we push A, B, C and D, and then when we pop we get D, C, B,
and A.
○ Very much like function calls; main calls A, A calls B, B calls C, C calls D; when D returns, it
must return to C, C to B, B to A, and A to main.
Introduction
● When something unexpected happens in a function, we know how we got to that
function thanks to the call stack; and we also have an option to let the calling function
handle the exception.
○ What do I mean by that?
○ Let’s say that your average method finds the average value in a list of integer values:
float average(int[] values) { … }
○ What if the list is empty? What will the method return? Zero? This assumes that there are n number of
zeros in the list.
○ You are working with positive integers, so return -1 so that the method that calls average should know
there is a problem with the list when it checks the return value and finds out that it is less than zero.
○ Instead we can throw an exception and let the calling function handle the empty array problem.
Maybe it will re-read the file for the values, maybe it will ask the user to enter the values again. We
don’t care: we want our list to have at least 1 value.
○ That is what I mean; we can pass the exception to the calling function…
Exception Objects
● This is a great opportunity to introduce objects that are not real-life objects.
● Once an exception is thrown, the runtime creates an object and hands it off to
the runtime system.
● This exception object contains information about the error, the type of
exception and the state of the program when it happened.
● This is very useful debugging information.
Exception Objects
● Once the exception is thrown, the runtime system attempts to find something
to handle it.
● It looks at the call stack to find a place that can handle it:
Catch or Specify
● We must honor the Catch or Specify Requirement.
● This means that code that might throw certain exceptions must be enclosed
by either of the following:
○ A try statement that catches the exception. The try must provide a handler for the exception.
○ A method that specifies that it can throw the exception. The method must provide a throws
clause that lists the exception.
● Code that fails to honor the Catch or Specify Requirement will not compile.
● Not all exceptions are subject to the Catch or Specify Requirement.
● To understand why, we need to look at the three basic categories of
exceptions, only one of which is subject to the Requirement.
Kinds of Exceptions
● The first kind of exception is the checked exception.
● These are exceptional conditions that a well-written application should anticipate
and recover from.
○ For example, suppose an application prompts a user for an input file name, then opens the file by
passing the name to the constructor for java.io.FileReader.
○ Normally, the user provides the name of an existing, readable file, so the construction of the
FileReader object succeeds, and the execution of the application proceeds normally.
○ But sometimes the user supplies the name of a nonexistent file, and the constructor throws
java.io.FileNotFoundException.
○ A well-written program will catch this exception and notify the user of the mistake, possibly prompting
for a corrected file name.
● Checked exceptions are subject to the Catch or Specify Requirement.
● All exceptions are checked exceptions, except for those indicated by Error,
RuntimeException, and their subclasses.
Kinds of Exceptions
● The second kind of exception is the error.
● These are exceptional conditions that are external to the application, and that
the application usually cannot anticipate or recover from.
○ For example, suppose that an application successfully opens a file for input, but is unable to
read the file because of a hardware or system malfunction.
○ The unsuccessful read will throw java.io.IOError.
○ An application might choose to catch this exception, in order to notify the user of the problem
— but it also might make sense for the program to print a stack trace and exit.
● Errors are not subject to the Catch or Specify Requirement.
● Errors are those exceptions indicated by Error and its subclasses.
Kinds of Exceptions
● The third kind of exception is the runtime exception.
● These are exceptional conditions that are internal to the application, and that the
application usually cannot anticipate or recover from.
● These usually indicate programming bugs, such as logic errors or improper use of an
API.
○ For example, consider the application described previously that passes a file name to the constructor for
FileReader.
○ If a logic error causes a null to be passed to the constructor, the constructor will throw
NullPointerException.
○ The application can catch this exception, but it probably makes more sense to eliminate the bug that
caused the exception to occur.
● Runtime exceptions are not subject to the Catch or Specify Requirement.
● Runtime exceptions are those indicated by RuntimeException and its subclasses.
● Errors and runtime exceptions are collectively known as unchecked exceptions.
Kinds of Exceptions
Catching and Handling Exceptions
● Very simple: try-catch-finally
● We try (or attempt) that might cause an exception in a try block.
● If there is an exception, we catch it, simply by listing possible exception types
in a series of catch blocks.
● If there is no exception, then none of the catch blocks are executed.
● The finally block always executes, even when there is no exception.
○ It is a good place to close the connections for example, because this block executes even
when there is an exception.
● Let’s take a look at an example.
1. public void writeList() {
2. PrintWriter out = null;
3.
4. try {
5. System.out.println("Entering try statement");
6.
7. out = new PrintWriter(new FileWriter("OutFile.txt"));
8. for (int i = 0; i < SIZE; i++) {
9. out.println("Value at: " + i + " = " + list.get(i));
10. }
11. } catch (IndexOutOfBoundsException e) {
12. System.err.println("Caught IndexOutOfBoundsException: "
13. + e.getMessage());
14.
15. } catch (IOException e) {
16. System.err.println("Caught IOException: " + e.getMessage());
17.
18. } finally {
19. if (out != null) {
20. System.out.println("Closing PrintWriter");
21. out.close();
22. }
23. else {
24. System.out.println("PrintWriter not open");
25. }
26. }
27. }
Catching More Than One Type of Exception with One Exception Handler
● A single catch block can handle more than one type of exception.
● This feature can reduce code duplication and lessen the temptation to catch
an overly broad exception.
● In the catch clause, specify the types of exceptions that block can handle, and
separate each exception type with a vertical bar (|):