views:

60

answers:

3

In Java, how would I use generics to create a max function that takes as parameters two Comparable objects of the same type and returns the larger one?

I tried:

public static <T extends Comparable> T max(T obj1, T obj2)
{
    return ( ((obj1).compareTo(obj2) >= 0) ? obj1 : obj2);
}

(It returns obj1 if they are both equal.)

The method is based on code I found at http://www.informit.com/articles/article.aspx?p=170176&amp;seqNum=3.

However, when I compile it I get this warning (compiling with -Xlint:unchecked): warning: [unchecked] unchecked call to compareTo(T) as a member of the raw type java.lang.Comparable

+8  A: 

That happens because you use the raw type Comparable, and the compiler can't be sure what you're comparing against, since compareTo uses the type parameter of Comparable. You need to parametrize Comparable as well:

public static <T extends Comparable<? super T>> T max(T obj1, T obj2)

You need to use ? super T since you may have a class A that extends a class B which implements Comparable<B>, but A doesn't implement Comparable<A>. So then you can pass max two A objects, and B matches ? super A, so you can call the compareTo method defined in B even for A objects. If you would use <T extends Comparable<T>> and tried to pass two A objects the compile would complain that they don't implement Comparable<A>, even though they inherit a compareTo method from B.

Andrei Fierbinteanu
Similar to `Collections.max()`.
Mark Peters
Thanks very much.
ladaghini
A: 

public static <T extends Comparable<T>> will remove warning.

Nikita Rybak
It's not a great API choice though since it's unnecessarily restrictive.
Mark Peters
A: 

Take a look at Guava's Ordering.max(a, b).

Willi