20-CS-694 Advanced Programming Techniques Spring 2012
Containers

Interfaces, Exceptions, Graphics, Animation, Threads, Reflection, Networking, RMI, JDBC, JNI

Previous     Next     All lectures

Type Safety, Iterators, and Generic Methods

Instructions for all applets:

All applets contain some buttons at the bottom and a JTextArea in the middle which shows the results of clicking the buttons. All applets are concerned with adding elements to a Vector or PriorityQueue container and one is also concerned with removing elements. The underlying theme of all this is how to support polymorphism, particularly for container classes.

Note:

Claim: "If your entire application has been compiled without unchecked warnings using javac -source 1.5, it is type safe." - from Oracle

Type safety: The absence of erroneous or undesirable program behavior caused by a discrepancy between differing data types.

    1.   Vector1Test.java

    This applet shows what can go wrong. A Vector can store a mix of objects. But what happens if an object is taken from a container and an operation that is intended for another type of object is applied to it? In this simple example integers and strings representing integers are contained in a Vector. The operation of concern is to append a number which is double the last number (could be a string or int) in the Vector. For the contained integers there is no problem, but when doubling is applied to a string an exception is thrown resulting in a "you're crazy" message being printed. Hit 'Add Int' to add an integer and hit 'Add String' to add a number as a string. Hit 'Double Last' to attempt to double the last number and append it.
 
    2.   Vector2Test.java

    This is a possible fix to the problem of the applet above. Objects stored in the vector are restricted to be of type Integer by the following declaration:
      Vector <Integer> v;
and instantiation
      v = new Vector <Integer> ();
Unfortunately, this is too restrictive and leaves out the possibility of adding string objects to the vector. Operate the buttons as above.
 
    3.   Vector3Test.java

    An interface called I is defined. This interface prototypes a method called dbl which is intended to output a number that is double some unspecified number. Classes A and B implement I. Class A objects hold an integer called number but class B objects hold a String object called str. Each implements dbl differently. Both A and B objects can be stored in the vector because it is declared and instantiated like this:
         Vector <I> v;
         v = new Vector <I> ();
Operate the buttons as above. The applet does what is expected.
 
    4.   Vector4Test.java

    There are no unchecked warning when this compiles. Yet clicking on 'Double Last' fails when the last element is a B object because the last element is allowed to be cast to an A object then a method of class A that has no counterpart in class B is invoked. This appears to show that Java is not type safe.
 
    5.   Collection1Test.java

    Some containers need an auxilliary function such as a Comparator. An example is the PriorityQueue. This example stores the same A and B objects as above. The Comparator is defined for interface I which is modified to require function val which is used to compare I objects. Classes A and B implement val accordingly.

This example also illustrates the use of an Iterator to move through a collection of objects (see the display) function.

 
    6.   Iterator1Test.java

    A function display prints the contents of any Collection. It uses the wildcard <?> to say that any Collection subtype is allowed as an argument to display.
 
    7.   Iterator2Test.java

    Classes UA and UB subclass U. Let v be a Vector of type UA and l be a LinkedList of type UB. It is desired to display UA and UB containers. But if display is prototyped like this:
  public String display(Collection <U> w) 
then code that uses display(v) or display(l) won't compile. The solution is:
  public String display(Collection <? extends U> w) 
 
    8.   Method1Test.java

    The method arrayToCollection is a generic method. Trying to write
  public void arrayToCollection (Object [] a, Collection <?> b) {
     for (int i=0 ; i < a.length ; i++) b.add(a[i]);
  }
does not compile - there is a type mismatch between <?> and Object. So the following is used
  public <T> Collection <T> arrayToCollection (T [] a, Collection <T> b) {
     for (int i=0 ; i < a.length ; i++) b.add(a[i]);
     return b;
  }
where a return value was added for fun. Now the types match. The <T> signifies that this is a generic method and specifies a type that is used in the parameter list.
 
    9.   Method2Test.java

    Three ways to protoype display are shown. These are
   public String display1 (Collection <?> w)
   public <T> String display2 (Collection <T> w)
   public <T extends I> String display3 (Collection <T> w)
The first form is used to support flexible sybtyping (polymorphism) which is the case in this example. The 2nd and 3rd forms are used when dependencies exist between the types of the parameters as was the case in the previous example.
 
    10.   Method3Test.java

    Use of the following:
     Collection <? super T>