CS51 - Spring 2010 - Lecture 22

  • Exercise 16.5.9

    Write a method that takes an array of words (i.e., Strings) as a parameter and returns true if and only if the array is in alphabetical order. Mixed case (i.e., both lower and upper case) can be used in the words, so be sure to take that into account. You may assume that the array is completely filled; there are no empty entries in the array.

  • compareTo
       - We can write:
          private void method(int x, int y){
             if( x < y ){
                // do something
             }
          }
       
       - What if we wanted to write:
          private void method(String x, String y ){
             if( x < y ){
                // so something
             }
          }

       - the comparison operators (<, >, <=, >=) only work on built-in data types, not on classes
       - However, seems like there is a natural ordering to String and we could compare them...
       - compareTo(String s) method
          - another method of the String class is the compareTo method
          - returns a number < 0 if this String is less than the String passed in
          - returns 0 if this String is equal to the String passed in
          - return a number > 0 if this String is greater than the String passed in
       - look at the Comparable interface (http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Comparable.html)
          - "Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object."
          - The String class implements the Comparable interface and has a compareTo method
          - can be used in general to compare objects if you want

  • show FragileColorMixer demo
       - what can go wrong here?
          - user can enter something that's not a number
             - NumberFormatException
          - user can enter something not in the range of 0 to 255
             - IllegalArgumentException

  • what other exceptions have we seen?
       - NullPointerException
       - ArrayIndexOutOfBoundsException
       - StringIndexOutOfBoundsException
       - ArithmeticException (e.g. divide by zero)

  • show FragileColorMixer code
       - how can we fix this?

  • show SaferColorMixer code
       - we can try to check ourselves
          - write a method:

          private boolean isInteger(String s)

       - What's annoying about this?
          - the other methods are already checking for problems and letting us know with an exception
          - we don't want to have to check this again
          - requires us to know things about the Color class!
          - hard to have some default behaviors, like, keep the current color if an error occurs

  • show AlmostIntelligibleColorMixer demo

  • show AlmostIntelligibleColorMixer code
       - rather than checking ourselves, we can "catch" exceptions
       - allows us to react to issues without having to explicitly check for them
       - Exception is a class!

  • try-catch blocks
       try
       {
          // code that may throw an exception
       }catch(<exception_class_name> <variable_name>){
          // code to run if an exception of type <exception_class_name> occurs
       }

  • general things to mention
       - exceptions are classes
          - they have member methods for accessing data
          - getMessage()
          - getStackTrace()
       - when an exception is thrown, any code after where the exception is thrown until the catch statement will NOT be executed
       - Hierarchy of exceptions
          - Exception
          -- RuntimeExeption
          --- IndexOutOfBoundsException
          ---- ArrayIndexOutOfBoundsException
          ---- StringIndexOutOFBoundsException
          --- IllegalArgumentException
          ---- NumberFormatException
       
          This is the inheritence hierarchy (i.e. extends)

  • the reason the AlmostIntelligibleColorMixer code works is that both IllegalArgumentException and NumberFormatException are both of type "Exception"

  • How can we improve the user experience?
       - we'd like to have different error messages for different issues/exceptions

  • multiple catch blocks
       try
       {
          // code that may throw an exception
       }catch(<exception_class_name1> <variable_name1>){
          // code to run if an exception of type <exception_class_name1> occurs
       }catch(<exception_class_name2> <variable_name2>){
          // code to run if an exception of type <exception_class_name2> occurs
       }

       - see if the exception falls in the first catch statement, if not, goes on

  • show IntelligibleColorMixer demo

  • show IntelligibleColorMixer code
       - what would happen if we changed the first catch to catch "Exception"?
          - code won't compile because we cannot reach the second catch statement
          - every IllegalArgumentException is an Exception

  • show StupidName demo
       - reads and writes output from the console
       - We've seen how to write it out: System.out.println()
       - We can read it in using System.in.read();
          - sits there waiting for a character to be read (process/program is "blocked")
          - when it does, returns that single character
          - reads it as an int, so we type cast it to a char
          - char nextChar = (char)System.in.read();
       - We want to write a method public String readLine() that uses System.in.read() and reads the line entered by the user (in our case the name)
       - How can we do it?

  • look at StupidName code
       - try it without try-catch block
       - compiler complains: "Unhandled exception type IOException"
       - StringBuffer class
          - remember, all String operations create a new String
          - if we're doing a lot of concatenating (e.g. one character at a time), very wasteful
          - StringBuffer is a mutable class
          - It's literally a long array of characters, some entries of which are unused (this type of data structure in CS is called a buffer)

  • checked vs. unchecked exceptions
       - The exceptions we've seen previously are called unchecked exceptions
          - we don't need to handle them if we don't want to
          - this checking is NOT enforced by the compiler
          - any exception that inherits from RuntimeException
       - All other exceptions are called checked exceptions
          - we must handle them
          - they are checked by the compiler and if they are not handled, a compiler error will occur

  • we have two options for dealing with checked exceptions
       - we can put a try catch block around the code
       - or, we can say that we don't want to deal with it here and announce to the word that our method throws that exception
       - we do this by appending: "throws <exception_class_name>" after the method description before the '{'

  • throwing exceptions
       - two reasons why a method is required to announce that is throws a particular exception
          - a method it calls throws an exception and the method doesn't handle it
          - the method explicitly throws an exception
       - throw new <exception_class_name>()
          - note it's just a constructor for a class
             <exception_class_name> exceptionToThrow = new <exception_class_name>();
             throw exceptionToThrow;
          - throw is similar to return... exits the current code

  • Look at StupidNameWithThrow code
       - String vs. StringBuffer
          - I could have used a String here, why a StringBuffer?
             - String is immutable. Everytime we modify it we create a new String, which can be expensive
             - StringBuffer is a mutable version of String. Use it if you're manipulating a String regularly.

  • show StupidNameWithBadName demo
       - how can we do this?
          - We could modify readName(), but what should we return if there is a problem?
          - We could modify our begin method to check if the name is good, but then we'd have to check that every time we called the readName method
          - Use an exception
             - We can define our own exceptions by extending Exception
             - look at BadNameException
                - usually end the class name with "Exception"
                - override getMessage() method
                - could in theory extend RuntimeException, in which case it would be an unchecked exception. In general, good coding practice to make all you exceptions checked.