A Few Exceptions, A Little IO, and Persistent Objects Rick Mercer
Exceptions When programs run, exceptional events occur a 3 rd thing that is sure in life Examples of "exceptional events" include Division by 0 Attempt to open a file that does not exist Array subscript out of bounds Integer.parseInt(input) when input is not a number Handle these with Java's exception handling General form on next slide
Handling exceptional events Put code that "throws" exceptional event into a try block and add a catch block try { code that causes exceptional events } catch( Exception anException ) { code that executes when an exception is thrown } If code in the try block throws an exception, control transfers to the catch block
Example Double.parseDouble may be passed a string that does not represent a valid number JTextField depositField = new JTextField(”ohNo"); JTextField depositField = new JTextField(”ohNo"); String numberAsString = depositField.getText(); String numberAsString = depositField.getText(); double amount = 0.0; double amount = 0.0; try { try { // the next message may "throw an exception" // the next message may "throw an exception" amount = Double.parseDouble(numberAsString); amount = Double.parseDouble(numberAsString); System.out.println("This message may not be sent"); System.out.println("This message may not be sent"); } catch (NumberFormatException nfe) { } catch (NumberFormatException nfe) { JOptionPane.showMessageDialog(null, JOptionPane.showMessageDialog(null, "'" + numberAsString + "' not valid number"); "'" + numberAsString + "' not valid number"); }
parseDouble method heading public static double parseDouble(String s) throws NumberFormatException Returns a number new represented by s Parameters: s - the string to be parsed Returns: the double value represented by the string argument Throws: NumberFormatException - if the string does not represent a valid number, 1oX.0 for example Many methods throw an exception ○ Your methods may too
A small piece of Java's large Exception hierarchy Code that throws RuntimeException need not be in a try block, all others must be in a try block Exception IOExceptionIllegalArgumentExceptionRunTimeException FileNotFoundExceptio nEOFExceptionArithmeticExceptionNumberFormatException
A few RuntimeExceptionsRuntimeExceptions parseDouble and parseInt when the String argument does not represent a valid number Integer expressions that result in division by 0 Sending a message to an object when the reference variable has the value of null Indexing exceptions: attempting to access an ArrayList element with an index that is out of range or a character in a string outside the range of 0 through length()-1
Two Unchecked Exceptions String str = null; String strAsUpperCase = str.toUpperCase(); java.lang.NullPointerException List stringList = new ArrayList (); stringList.add("first"); String third = stringList.get(1); IndexOutOfBoundsException: Index: 1, Size: 1
You can throw your own Exceptions which you’ve already done throws and throw are keywords The object after throw must be an instance of a class that extends the Throwable class public void deposit(double depositAmount) throws IllegalArgumentException { throws IllegalArgumentException { // Another way to handle preconditions // Another way to handle preconditions if (depositAmount <= 0.0) if (depositAmount <= 0.0) throw new IllegalArgumentException(); throw new IllegalArgumentException(); // This line won’t execute if the exception was thrown // This line won’t execute if the exception was thrown balance = balance + depositAmount; balance = balance + depositAmount;}
Circumventing Exceptions no try catch needed when a method throws Exception public void aMethod() { // Cause a 2 second pause (in PlayList perhaps) try { try { Thread.sleep(2000); Thread.sleep(2000); } catch (InterruptedException e) { } catch (InterruptedException e) { e.printStackTrace(); e.printStackTrace(); } } } } // This method declares it // might throw any Exception public void aMethod() throws Exception { // To cause a 2 second pause Thread.sleep(2000); } Thread.sleep(2000); } This is how you can circumvent exception handling
Need try /catch to open streams A stream is a sequence of items read from some source or written to some destination Input is read through input stream objects such as FileInputStream to read bytes Output is written through output stream objects such as FileWriter to print text We will use other streams to read and write persistent objects Write a large list of objects: writeObject(list)
Reading from a text file // The safe way to find a folder no matter where this program public static void main(String[] args) { double n1 = 0; // Must initialize since try may fail double n2 = 0; try { // Use a FileReader to read bytes from a disk file FileReader rawBytes = new FileReader("numbers.data"); BufferedReader inputFile = new BufferedReader(rawBytes); n1 = Double.parseDouble(inputFile.readLine()); n2 = Double.parseDouble(inputFile.readLine()); inputFile.close(); numbers.data
Can have several catch blocks A try block may have one to many catch blocks associated with it There are three things that could go wrong: } // <- end of try block from previous slide catch (FileNotFoundException fnfe) { // Do this if numbers.data was not found in the folder System.out.println("Could not find file: " + fnfe); } catch (IOException ioe) { // Do this if a readLine message failed System.out.println("Could not read from file"); } catch (NumberFormatException nfe) { // Do this if a line in the file was not a valid number System.out.println("A number on file was not valid"); }
new FileWriters must be in a try block A FileWriter object allows you to write to a text file PrintWriter diskFile = null; try { FileWriter charToBytesWriter = new FileWriter("out.text"); diskFile = new PrintWriter(charToBytesWriter); } catch (IOException ioe) { System.out.println("Could not create file"); } // Now diskFile understands print and println diskFile.print("First line with an int: "); diskFile.println(123); diskFile.close(); // Do NOT forget to close
Persistent Objects A persistent object is one that stays around after a program terminates Can be used by other programs, or when the same program begins again Entire objects can be written to a file on a disk and read from a file on a disk The objects must have implements Serializable Use ObjectOutputStream and writeObject Use ObjectInputStream and readObject
Write several object to disk String fileName = "onelist"; ArrayList list = new ArrayList (); list.add("A"); list.add("B"); list.add("C"); try { FileOutputStream bytesToDisk = new FileOutputStream(fileName); ObjectOutputStream outFile = new ObjectOutputStream(bytesToDisk); // outFile understands the writeObject(Object o) message. outFile.writeObject("A String object"); outFile.writeObject(list); outFile.writeObject(123); outFile.writeObject(new GregorianCalendar()); outFile.close(); // Always close the output file! } catch (IOException ioe) { System.out.println("Writing objects failed"); }
Read the list back in later try { FileInputStream rawBytes = new FileInputStream(fileName); ObjectInputStream inFile = new ObjectInputStream(rawBytes); // Need to cast Objects to the class they are known to be String str = (String)inFile.readObject(); list = (ArrayList ) inFile.readObject(); int anInt = (Integer) inFile.readObject(); GregorianCalendar day = GregorianCalendar)inFile.readObject(); System.out.println(" The string: " + str); System.out.println(" The list: " + list.toString()); System.out.println(" anInt: " + anInt); System.out.println("Day Written: " + day); inFile.close(); } catch (Exception e) { System.out.println("Something went wrong"); } Output The string: A String object The list: [A, B, C] anInt: 123 Day Written: java.util.GregorianCalendar [time= ,a
Serializable Any object from a class that lists this in its heading can be written to or read from a disk file implements Serializable It’s a tag, there are no methods to implement Many other Java classes do this already The primitive types are also Serializable Classes you write need the Serializable tag: public class BankAccount implements Comparable, Serializable
Serializable Instance Variables Not only must your class implement Serializable, so must all of the instance variables in the class or mark them as volatile You will know when you skip this when you see this exception: java.io.NotSerializableException: