chapter 9 exception handling• in chapter 7 we created a module class –a course holds a reference...

37
Chapter 9 Exception Handling Foundational Java Key Elements and Practical Programming Foundational Java 2nd edition by David Parsons © 2020

Upload: others

Post on 17-Apr-2021

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Chapter 9Exception Handling

Foundational JavaKey Elements and Practical Programming

Foundational Java 2nd edition by David Parsons © 2020

Page 2: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Exceptions

• Deal with unusual program flow

– technical issues

– business processes

• Cover a range of issues

– major programming errors

• dividing an integer by zero

• trying to invoke methods on a null reference

– minor business process exceptions

• invalid area code in an address

Foundational Java 2nd edition by David Parsons © 2020

Page 3: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Java Exceptions

• When an unusual condition arises in Java code it can throw an exception

• If nothing is done, the program will terminate

– We need to write code that is able to detect and handle any exceptions that may arise

• Compiler requires us to handle some exceptions

• Others we may anticipate ourselves

• Can also create exceptions explicitly

– Where business rule has been violated

Foundational Java 2nd edition by David Parsons © 2020

Page 4: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

The Exception Handling Hierarchy

Foundational Java 2nd edition by David Parsons © 2020

checked exceptions

unchecked errors

unchecked exceptions

Throwable

Error Exception

RuntimeException All Other Subclasses

Subclasses

Page 5: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Exception and Error Classes

• At the top of the hierarchy is ‘Throwable’

– any kinds of errors and exceptions that might occur in a Java program.

• Created by the JVM at run time or explicitly created using the ‘throw’ keyword

• Programmers need not try to deal with Errors

• Exceptions indicates conditions that a reasonable application might want to catch

Foundational Java 2nd edition by David Parsons © 2020

Page 6: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Checked and Unchecked Exceptions

• RuntimeExceptions can be thrown during the normal operation of the Java Virtual Machine

– ‘unchecked’ exceptions

– not required by the compiler to handle hem

• Exceptions that are direct subclasses of Exception are ‘checked’ exceptions

– the compiler will ensure that we do something in our application code to handle them

Foundational Java 2nd edition by David Parsons © 2020

Page 7: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Java Exception Handling Keywords

Keyword Usage

throws indicates that a method may throw an exception

try encloses a block of code that may throw an exception

catch follows ‘try’ - encloses a block of code that is invoked if a specified exception is thrown

finally follows ‘try’ or ‘catch’ - encloses a block of code that executes regardless of whether any exceptions are thrown

throw allows the programmer to explicitly throw an exception

Foundational Java 2nd edition by David Parsons © 2020

Page 8: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Checked Exceptions

• A checked exception must be handled, or the code will not compile

• This piece of code attempts to do some very crude keyboard input

• It will not compile, because the ‘read’ method of System.in throws a java.io.IOException

Foundational Java 2nd edition by David Parsons © 2020

int myChar = System.in.read(); // will not compile

System.out.println((char)myChar);

public int read(byte[] b) throws IOException

Page 9: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Handling Checked Exceptions

• Java will check, at compile-time, whether a program contains the code necessary to handle such an exception

• The exceptions that can be thrown by a method are stated in the method declaration

– Also in the Javadoc

Foundational Java 2nd edition by David Parsons © 2020

public abstract int read() throws IOException{

. . .}

Page 10: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Console Input

• In Eclipse, when we run a program that uses “System.in.read”, the output console is also used for input

• You terminate the input by pressing the Enter key. Only the first character typed will be captured by the “read” method.

• Here, the character “a” has been typed in and then echoed back to the same console.

Foundational Java 2nd edition by David Parsons © 2020

Page 11: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

‘throws’

• We can re-throw the exception to make the code compile

• Use the throws keyword

• Simply re-throwing a checked exception is not a particularly good way of dealing with it

• Ignoring exceptions will not lead to very robust applications.

Foundational Java 2nd edition by David Parsons © 2020

public static void main(String[] args) throws java.io.IOException

Page 12: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Catching Exceptions - ‘try’ and ‘catch’

• ‘anException’ must be one of the predefined exception classes

• Or an object of an Exception subclass we have written ourselves

• It must also be an exception that may actually be thrown by the code in the ‘try’ block

Foundational Java 2nd edition by David Parsons © 2020

try

{

// do this

}

catch(anException e)

{

// if it all went horribly wrong, do this

}

Page 13: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Handling A Checked Exception

• Must do something in the catch block

• printStackTrace displays exception information

Foundational Java 2nd edition by David Parsons © 2020

byte[] buffer = new byte[10];

String inputString= null;

try

{

System.in.read(buffer);

inputString = new String(buffer).trim();

}

catch(java.io.IOException e)

{

e.printStackTrace();

}

System.out.println(inputString);

Page 14: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Handling Unchecked Exceptions

• You can choose to handle unchecked exceptions

• This piece of code will compile, but would throw an ArrayIndexOutOfBoundsException at run time

Foundational Java 2nd edition by David Parsons © 2020

int[] intArray = new int[3];

for(int i = 0; i < 5; i++)

{

intArray[i] = i;

}

Page 15: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

ArrayIndexOutOfBoundsException

• This version catches the unchecked ArrayIndexOutOfBoundsException

Foundational Java 2nd edition by David Parsons © 2020

int[] intArray = new int[3];

for(int i = 0; i < 5; i++)

{

try

{

intArray[i] = i;

}

catch(ArrayIndexOutOfBoundsException e)

{

e.printStackTrace();

}

}

Page 16: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Exiting

• A ‘catch’ block is an opportunity to either ignore an exception and carry on, or do something to fix the problem at run time.

• Sometimes the program cannot reasonably recover

• We can explicitly exit the program using ‘System.exit’

– non-zero value indicates an abnormal exit

Foundational Java 2nd edition by David Parsons © 2020

catch(Exception e)

{

e.printStackTrace();

System.exit(1);

}

Page 17: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Catching Multiple Exceptions

• A try block can have multiple catch blocks

– Better than lots of ‘try-catch’ blocks

Foundational Java 2nd edition by David Parsons © 2020

byte[] buffer = new byte[10];

int inputInt = 0;

try

{

System.in.read(buffer);

String inputString = new String(buffer).trim();

inputInt = Integer.parseInt(inputString);

}

catch(java.io.IOException e)

{ … }

catch(NumberFormatException e)

{ … }

System.out.println(inputInt);

Page 18: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Ordering Multiple ‘catch’ Blocks

• If you use subclass and superclass exceptions, then you must order the handlers from the bottom to the top of the hierarchy

– Otherwise some catch blocks never get used

Foundational Java 2nd edition by David Parsons © 2020

try {

} catch (IOException e) {

} catch (Exception e) {

}

Page 19: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Exercise 9.1

• Create a reusable Keyboard class that includes static methods to read a single character, a String or an integer from the keyboard

• Include the required exception handling

• Add a static method to input a floating-point number, using the ‘parseDouble’ method of the Double class to implement the method

• Test your Keyboard class in a ‘main’ method

Foundational Java 2nd edition by David Parsons © 2020

Page 20: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Throwing an Exception with ‘throw’

• To explicitly throw an exception you create an exception object, and use the throw keyword

– If a business rule has been violated

Foundational Java 2nd edition by David Parsons © 2020

/**

* @param numberOfDays

* @throws IllegalArgumentException

*/

public void setNumberOfDays(int numberOfDays) throws IllegalArgumentException

{

if (numberOfDays < 1 || numberOfDays > 10)

{

throw new IllegalArgumentException(numberOfDays +

" is outside the valid range of 1 - 10");

}

Page 21: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Delegating Responsibility

• A method can delegate the responsibility for an exception– Whether this is appropriate depends on your application and the type of exception!

• Any code that calls the readChar method must now handle the IOException

Foundational Java 2nd edition by David Parsons © 2020

public char readChar() throws IOException

{

return (char)System.in.read();

}

Page 22: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Handling and Forwarding Exceptions

• You can handle an exception and then re-throw it

– The sender can then also be notified of the exception

Foundational Java 2nd edition by David Parsons © 2020

public char readChar() throws IOException

{

try

{

return (char)System.in.read();

}

catch (IOException e)

{

e.printStackTrace();

throw e;

}

}

Page 23: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Exercise 9.2

• Modify the ‘setName’ method from the Course class so that it throws a NullPointerException if the parameter passed to it is null

• The ‘throws’ keyword on a method signature may be followed by more than one exception type, in a comma separated list, for example:

• Modify the signature of the parameterized constructor of the Course class so that it throws both IllegalArgumentException and NullPointerException

• Modify your ‘main’ method so it can catch both types of exception. Use different constructors in separate ‘try…catch’ blocks

Foundational Java 2nd edition by David Parsons © 2020

public char readCharFromKeyboard() throws IOException, Exception

{ … }

Page 24: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Writing and Using Custom Exceptions

• You can create your own exception class by subclassing java.lang.Exception

• The new subclass of Exception typically has at least two constructors:

– a zero-arguments constructor

– a constructor that takes a String parameter

• The second constructor allows you to include a message when creating an instance of your Exception class

Foundational Java 2nd edition by David Parsons © 2020

public class TransactionException extends Exception

{

. . .

}

Page 25: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Constructors from Superclass

• Eclipse gives some assistance with overriding constructors

• In the “New Java Class” dialog, if the “Constructors from superclass” check box is checked, then stubs of all the inherited constructors will be added to the newly created class.

Foundational Java 2nd edition by David Parsons © 2020

Page 26: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Throwing a Custom Exception

• Throwing a custom exception is just like throwing one from a Java Exception class

• In this example the ‘debit’ method throws a TransactionException

Foundational Java 2nd edition by David Parsons © 2020

public void debit(double amount) throws TransactionException

{

if(this.getBalance() < amount)

{

throw new TransactionException("insufficient funds");

}

// if OK then carry on

}

Page 27: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

‘finally’ Blocks

• The finally block can follow ‘try’ or ‘catch’

• The finally block is optional, but when present, its code is always executed.

Foundational Java 2nd edition by David Parsons © 2020

try

{

// some code that we try to execute

}

catch (Exception ex)

{

// some code that will only be executed if the exception is thrown

}

finally

{

// some code that will always be executed,

// whatever happens in the ‘try’ and ‘catch’ blocks

}

Page 28: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

try-with-resources

• “try-with-resources” can be used where resources have been opened and need to be closed regardless of whether an exception has been thrown

• A “try” block followed by code that opens some kind of resource such as a file or a database connection

• The resource that is opened can be any object that implements java.lang.AutoCloseable

• “try-with-resources” will automatically try to close the resource if an exception is thrown

Foundational Java 2nd edition by David Parsons © 2020

try(code to open resource here) {

//…

}

// no requirement for “catch” or “finally” – these are optional

Page 29: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Exercise 9.3

• Create a BankAccount class with a ‘balance’ field and associated ‘getters’ and ‘setters’

• Implement the ‘debit’ method to either debit the balance or throw a TransactionException

• Write a ‘main’ method to test your debit method. In a ‘try’ block, set the original balance of the account, then make a number of debits until the exception is thrown

• Add a ‘finally’ block after your ‘try-catch’ block that simply displays a message on the console, demonstrating that the ‘finally’ block will be executed even if an exception has been thrown

Foundational Java 2nd edition by David Parsons © 2020

Page 30: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Re-throwing Custom Exceptions

• We can throw a different exception to the original one

Foundational Java 2nd edition by David Parsons © 2020

try {

courses[courseCount] = new Course(name, days, cost);

courseCount++;

}

catch(IllegalArgumentException e) {

throw new CourseConstructorException("Duration must be 1-10 days", e);

}

catch(NullPointerException e) {

throw new CourseConstructorException("Course name cannot be null", e);

}

catch(ArrayIndexOutOfBoundsException e) {

throw new CourseConstructorException("Cannot add any more courses", e);

}

Page 31: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Exercise 9.4

• In Chapter 7 we created a Module class

– A Course holds a reference to an array of Module objects

• Potentially, this could lead to an ArrayIndexOutOf-BoundsException

• Add some exception handling code to the Course class so that attempting to add too many modules to a course will not cause the program to crash.

• Write a test “main” method to test out your exception handling code.

Foundational Java 2nd edition by David Parsons © 2020

Page 32: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Exercise 9.5

• Create an Exception class called “ModuleException” as a subclass of Exception.

• Integrate this into your answer to Exercise 9.4 so that the ArrayIndexOutOf-BoundsException gets re-thrown as a ModuleException.

Foundational Java 2nd edition by David Parsons © 2020

Page 33: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Optional: An Alternative To “null”

• Dealing with NullPointerExceptions can lead to complex coding

• For example, this code checks the names of employees in a department

• If the first middle name of an employee is null, a NullPointerException will propagate up through the layers of objects

• Using the java.util.Optional class makes the code simpler because it removes the need for the conditional statement that checks for a null reference

Foundational Java 2nd edition by David Parsons © 2020

String nextMiddleName = getDepartment(dept).getEmployees().next().getMiddleNames().getFirst();

Page 34: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

“Employee” Class with “Optional” Field

• Here is part of a simple Employee class

• “MiddleName” is an “Optional” object

• “Optional<String>” means that this Optional object is of type String.

Foundational Java 2nd edition by David Parsons © 2020

public class Employee

{

private Optional<String> middleName;

Page 35: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

“Optional” Methods

• The “getMiddleName” method uses the “orElse” method to set up an alternate value if “middleName” is “null”. In this case it returns a String containing a space.

• The “setMiddleName” method sets the value of the Optional to be “ofNullable”. This method allows the value of the Optional to be “null”.

Foundational Java 2nd edition by David Parsons © 2020

public String getMiddleName()

{

return middleName.orElse(" ");

}

public void setMiddleName(String middleName)

{

this.middleName = Optional.ofNullable(middleName);

}

Page 36: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Code Example

• In this example, no exception is thrown

• The middle name for the second employee will be replaced with a space by the Optional object

• All we will see in the consoled is the “L”, the first letter of the first employee’s middle name.

Foundational Java 2nd edition by David Parsons © 2020

Department dept = new Department();

dept.addEmployee(new Employee("Martin","Luther","King"));

dept.addEmployee(new Employee("Malcolm",null,"X"));

for(Employee e1 : dept.getEmployees())

{

char midInitial = e1.getMiddleName().charAt(0);

System.out.println(midInitial);

}

Page 37: Chapter 9 Exception Handling• In Chapter 7 we created a Module class –A Course holds a reference to an array of Module objects • Potentially, this could lead to an ArrayIndexOutOf-BoundsException

Summary

• This chapter has explored various aspects of exception handling in Java, including the keywords “throws,” “try,” “catch,” “finally,” and “throw”

• The exception hierarchy divides exception types into checked exceptions, which are checked by the compiler, and unchecked exceptions.

• The Java runtime includes many exception types, but we can also create our own subclasses of Exception to represent custom exceptions

• “try-with-resources” can be used when opening resources such as files or database connections

• The “Optional” class can limit the likelihood of NullPointerExceptions being thrown by an application.

Foundational Java 2nd edition by David Parsons © 2020