DATA STRUCTURES Lecture: Exceptions, IO Slides adapted from Prof. Steven Roehrig CS 340 1.

34
DATA STRUCTURES Lecture: Exceptions, IO Slides adapted from Prof. Steven Roeh CS 340 1

Transcript of DATA STRUCTURES Lecture: Exceptions, IO Slides adapted from Prof. Steven Roehrig CS 340 1.

DATA STRUCTURES

Lecture: Exceptions, IO

Slides adapted from Prof. Steven Roehrig

CS 340 1

Today’s Topics• Older, and more modern, strategies for error handling.• Exception handling basics.• Some exception details:

• plain Exceptions vs. RuntimeExceptions• Exceptions containing information• Exception hierarchies

• What’s really practical using exceptions.

CS 340 2

Exception Handling• The compiler is supposed to report syntax errors, it but can’t discover many other types of errors:• casts to the wrong type• files that don’t exist• dividing by zero• indexing out of bounds• incorrect data formats• badly formed SQL queries• etc. etc.

• Unresolved, many of these errors prevent a program from continuing correctly.

CS 340 3

Exception Handling• We would like to be aware of these “exceptional”

situations, in hopes of• recovery• retrying• trying an alternate strategy• cleanup before exit• or, just finding out where the problem is!

• Nothing is more mystifying than a program that just “goes up in smoke”!

CS 340 4

Strategies for Error Handling

• In the course of programming, we constantly test for situations that routinely arise.

• We include logic to deal with the possibilities (switch, if-else, etc.).

• “Exceptional” situations are different. They are things that “should never happen”.

• We expect our code will be free from bugs, but…• We’re usually wrong.

CS 340 5

Strategies for Error Handling• Pre-testing the arguments to each function call.• Checking return values indicating error.• Setting and checking global error variables.• These are not formal methods, not part of the

programming language itself.• They require programmer discipline (but so does the use

of exceptions…).

CS 340 6

Example

void workOnArray(double[] myArray, int otherInfo) { int i = 0; // complicated calculation of array index i, using otherInfo myArray[i] = 3.14159; // what if i is out of bounds?}

CS 340 7

Example (cont.)

int workOnArray(double[] myArray, int otherInfo) { int i = 0; // complicated calculation of array index i, using otherInfo if (i >= 0 && i < myArray.length) { myArray[i] = 3.14159; return 0; // indicating everything OK } else return -1; // indicating an error}

CS 340 8

Potential Problem• What if workOnArray() needs to return a value (say, a

double)?• The “C” approach: values are returned through additional

reference arguments in the method – not directly in Java.• This quickly gets cumbersome.

CS 340 9

Another Technique: Globals• There are no true global variables in Java, but we “fake it”

all the time.• Write a class with static variables!• These are effectively available anywhere in a program,

and could be used to signal error conditions.

CS 340 10

Faking A Global Variable

public class MyGlobal { public static int indexError; MyGlobal() { } // indexError automatically initialized to 0}void workOnArray(double[] myArray, int otherInfo) { int i = 0; // complicated calculation of array index i, using otherInfo if (i >= 0 && i < myArray.length) { myArray[i] = 3.14159; } else MyGlobal.indexError = -1;}

CS 340 11

Three Important Issues• Where should the tests be done?

• Before the array is “indexed into”?• By the array class itself?

• Where should the error be reported?• Locally, or “further down” in the call stack?• Stroustrup says that authors of libraries can’t know their

user’s contexts, so can’t know what to do.• Who is responsible for adjudicating the error?• Exception handling in Java helps with these problems, but doesn’t completely solve them.

CS 340 12

Example

class MyException extends Exception { MyException(String message) { super(message); }}class MyExceptionThrower { void f() throws MyException { throw new MyException("Throwing MyException"); }}

CS 340 13

Example, cont

public static void main(String[] args){ MyExceptionThrower t = new MyExceptionThrower(); try { t.f(); } catch (MyException e) { e.printStackTrace(); } finally { System.out.println("Done"); } }

CS 340 14

Some Points

• f() must have “throws MyException”. Otherwise, compiler will complain.

• The compiler insists any call to this method be “tested” by enclosing it in a try block, or else we get an “unreported exception” error.

• If we do include a try block , there has to be a corresponding catch block or finally clause.

• When an exception is thrown, control goes to the matching catch block.

CS 340 15

More Points• All of this is true because our exception extended the

Exception class.• If we extend RuntimeException instead, we don’t need

to say throws, nor include try and catch blocks.• RuntimeExceptions are special; the Java runtime system

takes care of them automatically.

CS 340 16

Exceptions Always Get Caught

public class NeverCaught { static void g() { throw new RuntimeException(“From g()”); } static void f() { g(); } public static void main(String[] args) { f(); }}

CS 340 17

“Uncaught” Exceptions• If an exception makes it all the way “back” to main() without being caught, the Java runtime system calls printStackTrace() and exits the program:

• You can call printStackTrace() yourself if you want (and it’s useful to do it).

java.lang.RuntimeException: From g() at NeverCaught.f(NeverCaught.java:5)at NeverCaught.g(NeverCaught.java:8)at NeverCaught.main(NeverCaught.java:11)

Exception in thread "main"

CS 340 18

Call Stack, Normal Execution

main() called

main()main() main() main() main()

f() called

f()

g() called

f()g()

g() finished

f()

f() finished

time

CS 340 19

Call Stack, With Exception

main() called

main()main() main() main() main()

f() called

f()

g() called

f()g()

f()

exception thrown,g() has no handler,exit g()

search f() forhandler, exit f()

search main() forhandler, callprintStackTrace(),exit main()

CS 340 20

Catching Any Exception• We are always interested in exceptions that implement

the interface Exception.• So, a catch block like

catch(Exception e) { System.out.println(“Caught an exception”);}will catch any exception.

• If you have multiple catch blocks, this one should be last.

CS 340 21

Multiple Catch Blocks

• There may be several possible errors generated by a block of code:try { // try this // and this}catch(YourException e) { System.out.println(“Caught exception defined by you”);}catch(Exception e) { System.out.println(“Caught some other exception”);}

CS 340 22

Rethrowing an Exception

• Suppose you’ve caught an exception, and decided you can’t recover from it, but perhaps a higher context can.

• You can rethrow it:catch(Exception e) { System.out.println(“An exception was caught”); throw e;}

• The stack trace remains unchanged if it is caught higher up.

CS 340 23

Catching, Fixing and Retryingpublic class Retry { static int i = 0; public void f() { try { g(); } catch(Exception e) { System.out.println("Caught exception, i = " + i); i++; f(); } } void g() throws gException { if (i < 3) { throw new gException(); } else System.out.println("g() is working now"); }

CS 340 24

This Can Be Dangerouspublic class Retry { int i = 0; boolean fileIsOpen = false; public void f() { try { if (fileIsOpen) System.out.println("Opening an already opened file!"); else fileIsOpen = true; // i.e., open the file g(); fileIsOpen = false; // i.e., close the file } // file will be left open: Dangerous!

CS 340 25

What’s So Dangerous?• Just close the file in the catch block? Good idea! But,

what if some other exception were thrown, one that you didn’t catch?

catch(gException e) { System.out.println("Caught exception, i = " + i); i++; fileIsOpen = false; f(); } finally { fileIsOpen = false; }

CS 340 26

Exception Hierarchies

• Exceptions are classes, so can be in inheritance hierarchies.

• The usual polymorphism rules apply.• A handler for a superclass exception will catch a subclass exception.

• This makes it easy to catch groups of exceptions.• Exceptions are real objects (created with new), and so can have constructors and data members.

CS 340 27

Termination Vs. Resumption• Java makes it hard to complete this cycle:

• find a problem,• throw an exception,• fix the problem in the handler, and• go back to where you left off.

• This is called “resumption”.• Java assumes you don’t want to go back.• This is called “termination”.

CS 340 28

What You Can Do• Fix the problem and call the method that caused the exception once more.

• “Patch things up” and continue without retrying the method.

• Calculate some alternative result.• Do what you can in the current context, and rethrow the same exception to a higher context.

• Do what you can, and throw a different exception to a higher context.

• Terminate the program (how?).

CS 340 29

Java vs C#Program Structure

Operators

Choices

Loops

CS 340 30

Java vs C#: Exception Handling

31

Java C#

// Must be in a method that is declared to throw this exception Exception ex = new Exception("Something is really wrong."); throw ex;

try { y = 0; x = 10 / y; } catch (Exception ex) { System.out.println(ex.getMessage()); } finally { // Code that always gets executed }

Exception up = new Exception("Something is really wrong."); throw up; // ha ha

try { y = 0; x = 10 / y; } catch (Exception ex) { // Variable "ex" is optional Console.WriteLine(ex.Message); } finally { // Code that always gets executed }

CS 340

Java vs C#: Strings

32

Java C#

// My birthday: Oct 12, 1973 java.util.Calendar c = new java.util.GregorianCalendar(1973, 10, 12); String s = String.format("My birthday: %1$tb %1$te, %1$tY", c);

// Mutable string StringBuffer buffer = new StringBuffer("two "); buffer.append("three "); buffer.insert(0, "one "); buffer.replace(4, 7, "TWO"); System.out.println(buffer); // Prints "one TWO three"

// My birthday: Oct 12, 1973 DateTime dt = new DateTime(1973, 10, 12); string s = "My birthday: " + dt.ToString("MMM dd, yyyy");

// Mutable string System.Text.StringBuilder buffer = new System.Text.StringBuilder("two "); buffer.Append("three "); buffer.Insert(0, "one "); buffer.Replace("two", "TWO"); Console.WriteLine(buffer); // Prints "one TWO three"

CS 340

Java vs C#: Console I/O

33

Java C#

java.io.DataInput in = new java.io.DataInputStream(System.in); System.out.print("What is your name? "); String name = in.readLine(); System.out.print("How old are you? "); int age = Integer.parseInt(in.readLine()); System.out.println(name + " is " + age + " years old.");

int c = System.in.read(); // Read single char System.out.println(c); // Prints 65 if user enters "A"

// The studio costs $499.00 for 3 months. System.out.printf("The %s costs $%.2f for %d months.%n", "studio", 499.0, 3);

// Today is 06/25/04 System.out.printf("Today is %tD\n", new java.util.Date());

Console.Write("What's your name? "); string name = Console.ReadLine(); Console.Write("How old are you? "); int age = Convert.ToInt32(Console.ReadLine());Console.WriteLine(name + " is " + age + " years old.");

int c = Console.Read(); // Read single char Console.WriteLine(c); // Prints 65 if user enters "A"

// The studio costs $499.00 for 3 months. Console.WriteLine("The {0} costs {1:C} for {2} months.\n", "studio", 499.0, 3);

// Today is 06/25/2004 Console.WriteLine("Today is " + DateTime.Now.ToShortDateString());

CS 340

Java vs C#: File I/O

34

Java C#

import java.io.*;

// Character stream writingFileWriter writer = new FileWriter("c:\\myfile.txt");

writer.write("Out to file.\n"); writer.close();

// Character stream readingFileReader reader = new FileReader("c:\\myfile.txt");BufferedReader br = new BufferedReader(reader); String line = br.readLine(); while (line != null) { System.out.println(line); line = br.readLine(); } reader.close();

using System.IO;

// Character stream writingStreamWriter writer = File.CreateText("c:\\myfile.txt"); writer.WriteLine("Out to file."); writer.Close();

// Character stream readingStreamReader reader = File.OpenText("c:\\myfile.txt"); string line = reader.ReadLine(); while (line != null) { Console.WriteLine(line); line = reader.ReadLine(); } reader.Close();

CS 340