JAVA ASSIGNMENT
Course/.DS_Store
__MACOSX/Course/._.DS_Store
Course/assert-except-DLV01.pdf
Review of pre- and post-condi2ons
public sta2c double getAverage(ArrayList<Integer> numbers) { double sum = 0; for (int n:numbers) { sum += n; } return sum/numbers.size(); }
Consider the method getAverage shown below: • What would a sensible set of preconditions be? • What would be a good postcondition? • Why might it not be a sensible idea to return an “error value” such as
-1 if the preconditions are not met? • Why might it not be a sensible idea to write a message to the standard
error if the preconditions are not met?
1
Handling precondi2ons
• If the precondi2ons of our getAverage method are not met then – Returning -1 is probably not a good idea because you could have a list of
integers whose average genuinely was -1 – Wri2ng an error message to the standard error probably isn’t a good idea
either. We don’t know the context in which this method is called, so we don’t know where the standard error actually gets wriRen to, or whether anyone reads it.
• The only sensible things we can do are – Stop the program – it is wrong! – Throw an excep2on
2
asser2ons
• An asser2on is a statement that something should be true at a par2cular point in a program.
• “I assert …”
public sta2c double getAverage(ArrayList<Integer> numbers) { assert numbers != null : "List is null”; assert numbers.size() > 0: "List is empty"; double sum = 0; for (int n: numbers) { sum += n; } return sum/numbers.size(); }
A condition to check
Text of an message to be emitted if the condition is false
3
Form of asser2on in Java
assert boolExp; assert boolExpr: message;
where
boolExp is a Boolean expression and message is a string.
if (boolExpr) ; // do nothing – all is well
else quit program and print the message
4
Uses of asser2ons
Documen2ng programs – sta2ng what you can assume
or state confidently (assert): i = 0;
while (i != N && a[i] != x) i++;
assert i == N || a[i] == x; // this really ought to be true!
Checking possibly faulty assump2ons such as pre-condi2on of pop that
stack must not be empty
5
Design by Contract™
With Design by Contract™ we don’t check precondi2ons: it’s the responsibility of the client to ensure them. Example: int daysEarlier(int y1, int m1, int d1, int y2, int m2, int d2) // return number of days by which // date y1-m1-d1 is earlier (< 0 means later) than date y2-m2-d2
6
DaysEarlier: ‘defensive’ version
int daysEarlier(int y1, int m1, int d1, int y2, int m2, int d2) // returns number of days by which // y1-m1-d1 is earlier (< 0 means later) than y2-m2-d2 // or -999 if either or both not a valid date days = DaysEarlier(2013, 06, 11, 1943, 06, 31); if (days == -999) System.out.println("One or both dates not valid") else System.out.println("days earlier is " + days);
Outputs ‘One or both dates not valid’! Why?
7
Problem days = DaysEarlier(2013, 10, 15, 2011, 01, 20); if (days == -999) System.out.println(" One or both dates not valid ") else System.out.println(" days earlier is " + days); Says ‘One or both dates not valid’! Why? True story: Took three weeks to solve!
8
This formalised as … int daysEarlier(int y1, int m1, int d1, int y2, int m2, int d2) { // precondiJon assert isDate(y1, m1, d1) && isDate(y2, m2, d2) ; … // postcondiJon // ensure result is number of days by which // y1-m1-d1 is earlier (< 0 means later) than y2-m2-d2
9
Switching on asser2on checking in netbeans
To enable asser2on-checking in NetBeans 1. Right click on your project in the Projects tab 2. Select “Proper2es” and then “Run” 3. Type “-ea” or “-enableasser2ons” into the
“VMOp2ons” text box.
10
Switching on asser2on checking in netbeans
11
Asser2on handling • By default Java simply ignores asser2ons. This means that they don’t slow down execu2on of your code if you don’t want them checked.
• However if you specify the –ea op2on when you run your program, then the condi2ons associated with asser2ons are checked. If they are not true then an AsserJonError is thrown, a message associated with the assert statement is emiRed and the program stops.
• Asser.ons are for highligh.ng erroneous programs.
12
ARempt exercises 1 to 10
13
Excep2ons are for things you can’t foresee
Examples: • when trying to open a file and read from it, file by that name
might not exist, there might not be suitable data in the file. • when typing a value at the keyboard the user might type ill-
formed values, for example: integer wanted, other characters supplied.
14
What is an excep2on? • An excep2on is an object that
describes a problem that has occurred.
• Its getMessage method returns a descrip2on of the problem.
• There are many different kinds of excep2on. We have only shown a few of them on this slide.
Throwable
getMessage() printStackTrace()
Excep.on
Run.meExcep.on
IllegalArgumentExcep.on
IOExcep.on
FileNotFoundExcep.on NullPointerExcep.on
15
Checked and unchecked excep2ons
IllegalArgumentExcepJon, like all subclasses of RunJmeExcepJon is an unchecked excep2on. It is used to indicate that an argument (parameter) has an unacceptable value (violates a precondi2ons). All other excep2ons are checked. A method that can generate a checked excep2on must either catch it, or explicitly declare that it throws it.
Throwable
getMessage() printStackTrace()
Excep.on
Run.meExcep.on
IllegalArgumentExcep.on
IOExcep.on
FileNotFoundExcep.on 16
try … catch example
try { System.out.println("How old are you?"); int age= in.nextInt(); System.out.println("next year you'll be " + (age + 1)); } catch (InputMismatchExcep2on excep2on) { System.out.println("input not well formed"); } Note: { … } needed axer try and catch even if only one statement.
17
Specifying that your method throws an excep2on
[accessSpecifier] returnType methodName "(" (parameterType parameterName)* ")" "throws" Excep2onClass Excep2onClass*
Example: public void read(BufferedReader in) throws IOExcep2on
18
Checked excep2ons public sta2c void writeArray(ArrayList<Integer> nums) { PrintWriter out = new PrintWriter(new FileWriter("OutFile.txt")); for (int num : nums) { out.println(num); } out.close(); } This code will not compile because the
FileWriter constructor can throw an IOException, which is checked. We must either catch this exception, or explicitly declare that the method throws it.
19
Solu2on 1 Catch the excep2on
public sta2c void writeArray(ArrayList<Integer> nums) { try { PrintWriter out = new PrintWriter(new FileWriter("OutFile.txt")); for (int num : nums) { out.println(num); } out.close(); } catch (IOExcep2on ex) { System.out.println("Error opening file"); } }
20
Solu2on 2 add a “throws” clause
public sta2c void writeArray(ArrayList<Integer> nums) throws IOExcep2on { PrintWriter out = new PrintWriter(new FileWriter("OutFile.txt")); for (int num : nums) { out.println(num); } out.close(); }
The compiler will be happy with this, because we have acknowledged that the exception can be thrown. If there is an exception handler further down the call stack then it can be caught. Note that the word is “throws” not “throw”
Question: Which solution is better? 21
Which solu2on is beRer public sta2c void writeArray(ArrayList<Integer> nums) { try { PrintWriter out = new PrintWriter(new FileWriter("OutFile.txt")); for (int num : nums) { out.println(num); } out.close(); } catch (IOExcep2on ex) { System.out.println("Error opening file"); } }
This solution assumes that the method is being called in a context in which we can write a message to standard output and be confident that someone will see it. We can’t guarantee that this is true, so it is probably better to throw the exception and allow it to be caught by a handler that can deal with it more sensibly. 22
Throw early, catch late
• In general, a method should not catch an excep2on unless you can guarantee that it will be able to handle the excep2on in a sensible way.
• If you cannot do this then it is beRer to allow the excep2on to be thrown.
23
Crea2ng your own excep2on class
You define a new class of excep2on by extending some excep2on class: Example: public class InsufficientFundsExcep2on extends RunTimeExcep2on { public InsufficientFundsExcep2on() { } public InsufficientFundsExcep2on(String message) { super(message); } } When the excep2on is caught its message string can be retrieved using the getMessage method.
24
Usage: throw void withdraw(int amount) { if (amount > balance) { throw new InsufficientFundsExcep2on( "withdrawal of " + amount + " exceeds balance of " + balance); else balance-= amount; }
25
Shame on you! try { withdraw(amount); } catch (InsufficientFundsExcep2on ex) { System.out.println(ex.getMessage()); System.out.println("Shame on you for even asking! "); }
26
And finally…
public sta2c void writeArray (ArrayList<Integer> nums) throws IOExcep2on { PrintWriter out = null; try { out = new PrintWriter(new FileWriter("OutFile.txt")); for (int num : nums) { out.println(num); } } finally { if (out != null) { out.close(); } } }
The finally block is executed if any exception is thrown within the try block. After the finally clause has been executed the exception will be thrown. Note that we have not caught the exception.
We still need the throws clause, because the method can still throw an IOException
27
Try blocks with both catch and finally blocks
public sta2c void writeArray5(ArrayList<Integer> nums) { PrintWriter out = null; try { out = new PrintWriter(new FileWriter("OutFile.txt")); for (int num : nums) { out.println(num); } } catch (IOExcep2on ex) { System.out.println("Error opening file"); } finally { if (out != null) { out.close(); } } }
The finally block is executed if any exception is thrown within the try block. If an IOException was generated in the try block then we would execute both the catch block, and the finally block.
We no longer need the throws clause, because the method catches the IOException
28
Try blocks with both catch and finally blocks
• Although Java allows you to add both a catch block and a finally block to the same try block, that does not mean it is a sensible thing to do.
• The circumstances in which a finally block would be useful are oxen different to those in which a catch block would be sensible. Furthermore code with both blocks can be difficult to understand.
29
Summary
• Asser2ons are for dealing with broken pre- or postcondi2ons or for asser2ng things that really must be true (or else the program is wrong).
• Excep2ons are for, such as invalid input, broken network links. things that cannot be foreseen
30