Quick Quiz
/* * Mark this class compile, WITHOUT removing any code * It should print, "Not an integer" if the number isn't an integer * It should print, "problem with input" if the readLine() fails * * Do not use "throws" * * You may safely ignore any of my minor syntax errors */ class Quiz { public static void main (String[] args) { BufferedReader br = new BufferedReader (new InputStreamReader (System.in)); String line = ""; int number = 0; try { line = br.readLine(); number = Integer.parseInt(line); System.out.println ("100 * the number is " + 100*number); } catch (IOException e) { System.out.println ("Problem with input."); } catch (NumberFormatException nfe) { System.out.println ("Not an integer"); } catch (Exception e) { System.out.println ("Unknown error occured: " + e.getMessage()); } } }
A More Complex Example
In class today, we developed a more sophisticated example that employed exeptions. Below is the end result of that effort. Discussion follows.
import java.io.*; class NameGame { private class MenuChoiceException extends Exception { public MenuChoiceException (String message) { super (message); } } private static final String FIRST_NAME = "Greg"; private static final String MIDDLE_NAME = "Michael"; private static final String LAST_NAME = "Kesden"; private static final int MAX_RETRIES = 3; private static char getOption (String prompt, String options) throws MenuChoiceException { BufferedReader br = new BufferedReader (new InputStreamReader (System.in)); char option = ''; System.out.println (prompt); try { option = br.readLine().charAt(0); } catch (IOExcpetion ioe) { throw new MenuChoiceException ("Unable to read choice, IO problem."); } boolean legalOption = false; for (int retry = 0; retry < MAX_RETRIES; retry++) { for (int index = 0; index < options.length(); index++) { if (option == options.charAt(index)) legalOption = true, break; } if (legalOption) break; } if (legalOption) return choice; // if the for loop goes through all the options and then does not // find the correct char's, the Exception is then thrown throw new MenuChoiceException ("Too many retries"); } public static void main (String[] args) { boolean quit = false; while (!quit) { char choice = ''; try { choice = getOption("F, M, L, or Q", "FMLQfmlq"); } catch (MenuChoiceException mce) { System.out.println ("A lot of retries...please pay attention."); System.out.println ("The choices are 'F, M, L, or Q."); continue; } switch (choice) { case 'f': case 'F': System.out.println (FIRST_NAME); break; case 'm': case 'M': System.out.println (MIDDLE_NAME); break; case 'l': case 'L': System.out.println (LAST_NAME); break; case 'q': case 'Q': quit = true; break; } // switch } // while (!quit) } // main }
Observation #1: Defining A New Type of Exception
Above, we defined a new type of Exception. Nothing special -- basically "cookie cutter." The only thing to notice here is that it is "private". The reason for this is that it never makes its way out of our class -- so why make it accessible to others?
private class MenuChoiceException extends Exception { public MenuChoiceException (String message) { super (message); } }
Observation #2: Handling The IOException
Notice that the possibility of an IOException from the br.readLine() is managed using a try-catch, instead of the previously-familiar "throws" clause:
try { option = br.readLine().charAt(0); } catch (IOExcpetion ioe) { throw new MenuChoiceException ("Unable to read choice, IO problem."); }Observation #3: The Options String
The way we verified that the user made an allowed choice is a bit unique. We create a String that contains each of the single-character options. We then walk through this String trying to match the user's choice against one of its characters. If we match -- hurray! If, after considering each option within the string, we do not -- it is an error.
boolean legalOption = false; for (int retry = 0; retry < MAX_RETRIES; retry++) { for (int index=0; index < options.length(); index++) { if (option == options.charAt(index)) legalOption = true, break; } if (legalOption) break; }Observation #4: Check out the "throw"
Once we exit the loop, legalOption either remains false -- or it has been changed to true because it matched a valid option. If it became true -- we return the user's choice. This is an example of the normal control flow in a Java program.But, if it isn't true, we make use of Java's exception-handling mechanism. This is done by using "throw." We generate a "new" [MenuChoice]Exception -- and then "throw" it to start the Exception handling.
boolean legalOption = false; for (int retry = 0; retry < MAX_RETRIES; retry++) { for (int index=0; index < options.length(); index++) { ... } } if (legalOption) return choice; // if legalOption is false it will then throw this Exception throw new MenuChoiceException ("Too many retries"); }In order for this to work, we needed to include the "throws" clause in the method's declaration. This documents the possibility of the Exception to a programmer who might call this method -- and it allows Java to ensure that the programmer acknowledged this possibility with a try-catch block or with an "throws" clause upstream in the call chain.
private static char getOption (String prompt, String options) throws MenuChoiceException {Observation #5: Catching the Exception
The main() method, which calls getOption(), is not delcared to "throw" any type of Exception. This is because the Exception is properly handled within the method via a try-catch block.Note below that the main method contains no "throws clause":
public static void main (String[] args) {Notice below that the getOption() method, which can throw a MenuOptionException, is surrounded with a try-block. Notice that this try-block preceeds an applicable catch-block. In particular, the catch-block catches exactly the MenuOptionException.
while (!quit) { try { // click on the link to see the method getOption("F, M, L, or Q", "FMLQfmlq") choice = getOption("F, M, L, or Q", "FMLQfmlq"); } catch (MenuChoiceException mce) { System.out.println ("A lot of retries...please pay attention."); System.out.println ("The choices are 'F, M, L, or Q."); continue; } }