Search code examples
javagenericsinterfacecomparableunchecked

Java: unchecked call to compareTo(T)


 1  class test {
 2      public static int compare0(Comparable x, Comparable y) {
 3          return x.compareTo(y);
 4      }

 5      public static int compare1(Object x, Object y) {
 6          return ((Comparable) x).compareTo((Comparable) y);
 7      }

 8      public static int compare2(Object x, Object y) {
 9          Comparable p = (Comparable) x;
10          Comparable q = (Comparable) y;
11          return (p).compareTo(q);
12      }

13      public static void main(String[] args) {
14          Comparable zero = new Integer(0);
15          Comparable one = new Integer(1);
16          int c = (zero).compareTo(one);
17      }
18  }

Compiling the code above produces 4 warnings:

% javac -Xlint:unchecked test.java
test.java:3: warning: [unchecked] unchecked call to compareTo(T) as a member of the raw type java.lang.Comparable
    return x.compareTo(y);
                      ^
test.java:7: warning: [unchecked] unchecked call to compareTo(T) as a member of the raw type java.lang.Comparable
    return ((Comparable) x).compareTo((Comparable) y);
                                     ^
test.java:13: warning: [unchecked] unchecked call to compareTo(T) as a member of the raw type java.lang.Comparable
    return (p).compareTo(q);
                        ^
test.java:19: warning: [unchecked] unchecked call to compareTo(T) as a member of the raw type java.lang.Comparable
    int c = (zero).compareTo(one);
                            ^
4 warnings

I tried many more variants, but the warnings remain. What's the correct way to write and call the test.compare method above?

Thanks!

PS: test.compare is only an example; I don't need such a function; but I need to implement a function that, like test.compare, needs to have Comparable-implementing objects in its signature.

PS2: I've been programming for 25+ years, I even programmed Java for a while around 10 years ago, but using Java now (required by my job) is driving me berserk. For an experienced programmer, learning Java is much harder than it looks. There's so mu\ ch stuff on learning Java out there, 99% of which is at best outdated, or pitched to rank programming novices (i.e. massively verbose), and at worst is outright garbage... I have yet to find a reference on Java that will let me quickly zero in the answer to the question above.


Solution

  • You should declare the compare method with a generic argument.

    public class ThisTest
    {
        public static <T extends Comparable<T>> int compare(T x, T y) {
            if (x == null) 
                return -(y.compareTo(x));
            return x.compareTo(y);
        }
    
        public static void main()
        {
            // Type inferred
            int c = compare(Integer.valueOf(0), Integer.valueOf(1));
            // Explicit generic type parameter
            c = ThisTest.<Integer>compare(Integer.valueOf(0), Integer.valueOf(1));
        }
    }