0% found this document useful (0 votes)
11 views32 pages

Lecture 07 Exception Handling

Uploaded by

anonimolankaan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views32 pages

Lecture 07 Exception Handling

Uploaded by

anonimolankaan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 32

Lecture 07: Exception

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 (|):

1. catch (IOException|SQLException ex) {


2. /* handle exception */
3. }
Specifying the Exceptions Thrown by a Method
● It's appropriate for code to catch exceptions that can occur within it.
● In other cases, however, it's better to let a method further up the call stack
handle the exception.
○ For example, if you were providing the average method we have discussed earlier as part of
a package of classes, you probably couldn't anticipate the needs of all the users of your
package.
○ In this case, it's better to not catch the exception and to allow a method further up the call
stack to handle it.
● We do this by adding a throws clause to the method declaration.
○ The throws clause comprises the throws keyword followed by a comma-separated list of all
the exceptions thrown by that method.
○ The clause goes after the method name and argument list and before the brace that defines
the scope of the method
Specifying the Exceptions Thrown by a Method
1. public float average(int[] myArray) throws Exception, RuntimeException
{
2. if(myArray.length == 0) {
3. throw new Exception("Array has no elements");
4. }
5. /* ... */
6. }
Picking up Exceptions
● Consult the documentation.
● https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Except
ion.html

● There are so many exception types here.


● Let’s check IOException.
● Signals that an I/O exception of some sort has occurred. This class is the
general class of exceptions produced by failed or interrupted I/O operations.
● Remember the “Catch or Specify” requirement.
Create your own Exception
● Just extend one of the exceptions.
● Let’s work on the average method.
● We can create an exception called EmptyArrayException that extends
RuntimeException.
1. class EmptyArrayException extends RuntimeException {
2. public EmptyArrayException() {
3. super("Array has no elements");
4. }
5. }
6.
7. class MyAverage {
8. public static float average(int[] myArray)
9. throws EmptyArrayException {
10.
11. if (myArray.length == 0) {
12. throw new EmptyArrayException();
13. }
14.
15. float sum = 0;
16. for(int i=0;i<myArray.length;i++) sum += myArray[i];
17. return sum / (float)myArray.length;
18. }
19. }
20. Notice the call stack!
21. public class MyDriver { $ javac MyDriver.java
22. public static void main(String[] args){ $ java MyDriver
23. int[] m = {}; Exception in thread "main" EmptyArrayException: Array has no
24. System.out.println(MyAverage.average(m)); elements
25. } at MyAverage.average(MyDriver.java:12)
26. } at MyDriver.main(MyDriver.java:24)
Create your own Exception
● You should write your own exception classes if you answer yes to any of the
following questions; otherwise, you can probably use someone else's.
○ Do you need an exception type that isn't represented by those in the Java platform?
○ Would it help users if they could differentiate your exceptions from those thrown by classes
written by other vendors?
○ Does your code throw more than one related exception?
○ If you use someone else's exceptions, will users have access to those exceptions? A similar
question is, should your package be independent and self-contained?
Chained Exceptions
● An application often responds to an exception by throwing another exception.
● In effect, the first exception causes the second exception.
● It can be very helpful to know when one exception causes another.
● Chained Exceptions help the programmer do this.
Assertions
● When implementing and debugging a class, it’s sometimes useful to state
conditions that should be true at a particular point in a method.
● Assertions help ensure a program’s validity by catching potential bugs and
identifying possible logic errors during development.
● Preconditions and postconditions are two types of assertions.
● Java includes two versions of the assert statement for validating assertions
programmatically.
● assert evaluates a boolean expression and, if false, throws an
AssertionError (a subclass of Error).
Assertions
● You use assertions primarily for debugging and identifying logic errors in an
application.
● You must explicitly enable assertions when executing a program
○ They reduce performance,
○ They are unnecessary for the program’s user.
● To enable assertions, use the java command’s -ea command-line option.
Finally
● Let’s work with a resource, so that we can release it in the finally block.
● A resource is an object that must be closed after the program is finished with
it.
● In the example that follows, the file is closed even when there is an I/O
exception.
1. import java.io.PrintWriter;
2. import java.io.FileWriter;
3. import java.io.IOException;
4.
5. public class MyResource {
6.
7. public static void main(String[] args) {
8. PrintWriter out = null;
9. try {
10. out = new PrintWriter(new FileWriter("OutFile.txt"));
11. out.println("Hello");
12. }
13. catch (IOException e) {
14. System.out.println(e);
15. }
16. finally {
17. if(out != null) {
18. out.close();
19. }
20. }
21. }
22. }
Try-with-resources
● The try-with-resources statement is a try statement that declares one or
more resources.
● Typically we place the resource release in a finally block to ensure that a
resource is released, regardless of whether there were exceptions when the
resource was used in the corresponding try block.
● The try-with-resources statement ensures that each resource is closed at
the end of the statement.
● Any object that implements java.lang.AutoCloseable, which includes all
objects which implement java.io.Closeable, can be used as a resource.
● Let’s rework the example in finally.
1. import java.io.PrintWriter;
2. import java.io.FileWriter;
3. import java.io.IOException;
4.
5. public class MyResource {
6.
7. public static void main(String[] args) {
8.
9. try (PrintWriter out = new PrintWriter(new FileWriter("OutFile.txt"))) {
10. out.println("Hello");
11. }
12. catch (IOException e) {
13. System.out.println(e);
14. }
15. }
16. }
Try-with-resources
● With try-with-resources, we add a parenthesis right after the try clause which
initializes a resource that implements the AutoCloseable interface.
References
● Oracle Java Documentation, Exceptions:
https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html
● Course slides of the textbook ‘Java How to Program, 10/e (Early Objects),
Global Edition, Paul Deitel and Harvey Deitel, Pearson’
● Slides by Kaya Oğuz and Senem Kumova Metin

You might also like