-1

I would like to resolve this compiler warning:

unchecked call to compareTo(T) as member of the raw type java.lang.Comparable

My goal is to compare two java.lang.Object objects of unknown (background) type using following method.

public static boolean Compare(Object o1, Object o2) {
    //check if both classes are the same
    if(!o1.getClass().equals(o2.getClass())) {
       return false;
    } 

    if(Comparable.class.isAssignableFrom(o1.getClass()) 
        && Comparable.class.isAssignableFrom(o2.getClass())) {
       //only if both objects implement comparable
       return Comparable.class.cast(o1).compareTo(Comparable.class.cast(o2)) == 0;

    }
    //other comparison techniques...
}

I know that the problem is that the method casts both objects to Comparable (Comparable<Object>), but Object does not implements Comparable.

The code itself works, but the compiler throws a warning when using its -Xlint:unchecked parameter.

Goals:

  • remove the compiler warning
  • keep out of other 'unchecked' warnings
  • avoiding using @SupressWarning
  • keep Compare method non-generic
t4dohx
  • 675
  • 4
  • 24
  • 3
    You can't. SuppressWarning is exactly for that: the compiler warns you that you're doing something which it can't check if it's type-safe. Either you make your code type-safe, or you tell the compiler: I know, I know, please trust me. And that's what SuppressWarning is for. You should respect the Java conventions, though. That's quite easy, and doesn't involve suppressing warnings. – JB Nizet Mar 09 '19 at 17:42
  • 1
    If you don't know if the two classes implement `Comparable`, it makes no sense to compare them. BTW, it looks like you try to implement `equals`. –  Mar 09 '19 at 17:42
  • @JB Nizet - Thank you, seems like I'll use SupressWarning then. – t4dohx Mar 09 '19 at 17:48
  • @Lutz Horn - I am not implementing equals, I just want to compare results of two methods whose are invoked dynamically using reflection. – t4dohx Mar 09 '19 at 17:49

1 Answers1

0

You can't easily escape the compiler warnings. It is its job to tell you when you're doing type manipulations that can break at runtime. The only way to fulfill your goal is to do even more unchecked manipulations, like this :

    if(Comparable.class.isAssignableFrom(o1.getClass()) 
            && Comparable.class.isAssignableFrom(o2.getClass())) {
        // Cache this somewhere if you're really going to use it
        Method compareTo = Comparable.class.getMethod("compareTo", Object.class);
        Integer result = (Integer) compareTo.invoke(o1, o2);

        return result == 0;

    }

The best option is still to use @SuppressWarnings once when converting the objects, and get on with it. If somehow you can't guarantee the type safety of your parameters, it's perfectly OK to use it.

ttzn
  • 2,543
  • 22
  • 26