Bounds for Type Variables

   


Sometimes, a class or a method needs to place restrictions on type variables. Here is a typical example. We want to compute the smallest element of an array:

 class ArrayAlg {    public static <T> T min(T[] a) // almost correct    {       if (a == null || a.length == 0) return null;       T smallest = a[0];       for (int i = 1; i < a.length; i++)          if (smallest.compareTo(a[i]) > 0) smallest = a[i];       return smallest;    } } 

But there is a problem. Look inside the code of the min method. The variable smallest has type T, which means that it could be an object of an arbitrary class. How do we know that the class to which T belongs has a compareTo method?

The solution is to restrict T to a class that implements the Comparable interface a standard interface with a single method, compareTo. You achieve this by giving a bound for the type variable T:

 public static <T extends Comparable> T min(T[] a) . . . 

Actually, the Comparable interface is itself a generic type. For now, we will ignore that complexity.

Now, the generic min method can only be called with arrays of classes that implement the Comparable interface, such as String, Date, and so on. Calling min with a Rectangle array is a compile-time error because the Rectangle class does not implement Comparable.

C++ NOTE

In C++, you cannot restrict the types of template parameters. If a programmer instantiates a template with an inappropriate type, an (often obscure) error message is reported inside the template code.


You may wonder why you use the extends keyword rather than the implements keyword in this situation after all, Comparable is an interface. The notation


<T extends BoundingType>

expresses that T should be a subtype of the bounding type. Both T and the bounding type can be either a class or an interface. The extends keyword was chosen because it is a reasonable approximation of the subtype concept, and the Java designers did not want to add a new keyword (such as sub) to the language.

A type variable or wildcard can have multiple bounds, for example,

 T extends Comparable & Serializable 

The bounding types are separated by ampersands (&) because commas are used to separate type variables.

As with Java inheritance, you can have as many interface supertypes as you like, but at most one of the bounds can be a class. If you have a class as a bound, it must be the first one in the bounds list.

In the next sample program (Example 13-2), we rewrite the minmax method to be generic. The method computes the minimum and maximum of a generic array, returning a Pair<T>.

Example 13-2. PairTest2.java
  1. import java.util.*;  2.  3. public class PairTest2  4. {  5.    public static void main(String[] args)  6.    {  7.       GregorianCalendar[] birthdays =  8.          {  9.             new GregorianCalendar(1906, Calendar.DECEMBER, 9), // G. Hopper 10.             new GregorianCalendar(1815, Calendar.DECEMBER, 10), // A. Lovelace 11.             new GregorianCalendar(1903, Calendar.DECEMBER, 3), // J. von Neumann 12.             new GregorianCalendar(1910, Calendar.JUNE, 22), // K. Zuse 13.          }; 14.       Pair<GregorianCalendar> mm = ArrayAlg.minmax(birthdays); 15.       System.out.println("min = " + mm.getFirst().getTime()); 16.       System.out.println("max = " + mm.getSecond().getTime()); 17.    } 18. } 19. 20. class ArrayAlg 21. { 22.    /** 23.       Gets the minimum and maximum of an array of objects of type T. 24.       @param a an array of objects of type T 25.       @return a pair with the min and max value, or null if a is 26.       null or empty 27.    */ 28.    public static <T extends Comparable> Pair<T> minmax(T[] a) 29.    { 30.       if (a == null || a.length == 0) return null; 31.       T min = a[0]; 32.       T max = a[0]; 33.       for (int i = 1; i < a.length; i++) 34.       { 35.          if (min.compareTo(a[i]) > 0) min = a[i]; 36.          if (max.compareTo(a[i]) < 0) max = a[i]; 37.       } 38.       return new Pair<T>(min, max); 39.    } 40. } 


       
    top



    Core Java 2 Volume I - Fundamentals
    Core Java(TM) 2, Volume I--Fundamentals (7th Edition) (Core Series) (Core Series)
    ISBN: 0131482025
    EAN: 2147483647
    Year: 2003
    Pages: 132

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net