img
Here, T is bounded by a class called MyClass and an interface called MyInterface. Thus,
any type argument passed to T must be a subclass of MyClass and implement MyInterface.
Using Wildcard Arguments
As useful as type safety is, sometimes it can get in the way of perfectly acceptable constructs.
For example, given the Stats class shown at the end of the preceding section, assume that
you want to add a method called sameAvg( ) that determines if two Stats objects contain
arrays that yield the same average, no matter what type of numeric data each object holds.
For example, if one object contains the double values 1.0, 2.0, and 3.0, and the other object
contains the integer values 2, 1, and 3, then the averages will be the same. One way to
implement sameAvg( ) is to pass it a Stats argument, and then compare the average of that
argument against the invoking object, returning true only if the averages are the same. For
example, you want to be able to call sameAvg( ), as shown here:
Integer inums[] = { 1, 2, 3, 4, 5 };
Double dnums[] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
Stats<Integer> iob = new Stats<Integer>(inums);
Stats<Double> dob = new Stats<Double>(dnums);
if(iob.sameAvg(dob))
System.out.println("Averages are the same.");
else
System.out.println("Averages differ.");
At first, creating sameAvg( ) seems like an easy problem. Because Stats is generic and its
average( ) method can work on any type of Stats object, it seems that creating sameAvg( )
would be straightforward. Unfortunately, trouble starts as soon as you try to declare a
parameter of type Stats. Because Stats is a parameterized type, what do you specify for
Stats' type parameter when you declare a parameter of that type?
At first, you might think of a solution like this, in which T is used as the type parameter:
// This won't work!
// Determine if two averages are the same.
boolean sameAvg(Stats<T> ob) {
if(average() == ob.average())
return true;
return false;
}
The trouble with this attempt is that it will work only with other Stats objects whose type is
the same as the invoking object. For example, if the invoking object is of type Stats<Integer>,
then the parameter ob must also be of type Stats<Integer>. It can't be used to compare the
average of an object of type Stats<Double> with the average of an object of type Stats<Short>,
for example. Therefore, this approach won't work except in a very narrow context and does
not yield a general (that is, generic) solution.
Search WWH :
Custom Search
Previous Page
Java SE 6 Topic Index
Next Page
Java SE 6 Bookmarks
Home