Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

incomparable types: int and Number in java 8

Suppose I have the following code:

class proba {
    boolean fun(Number n) {
        return n == null || 0 == n;
    }
}

This compiles without problem using openjdk 7 (debian wheezy), but fails to compile when using openjdk 8, with the following error (even when using -source 7):

proba.java:3: error: incomparable types: int and Number
    return n == null || 0 == n;
                          ^
1 error

How to go around this:

  • Is there a compiler option for this construct to continue working in java 8?
  • Should I make lots of consecutive ifs with instanceof checks of all of Number's subclasses and casting and then comparing one-by one? This seems ugly...
  • Other suggestions?
like image 719
P.Péter Avatar asked Dec 11 '22 18:12

P.Péter


2 Answers

This is actually a bugfix (see JDK-8013357): the Java-7 behavior contradicted the JLS §15.21:

The equality operators may be used to compare two operands that are convertible (§5.1.8) to numeric type, or two operands of type boolean or Boolean, or two operands that are each of either reference type or the null type. All other cases result in a compile-time error.

In your case one operand is numeric type, while other is reference type (Number is not convertible to the numeric type), so it should be a compile-time error, according to the specification.

This change is mentioned in Compatibility Guide for Java 8 (search for "primitive").

Note that while your code compiles in Java-7 it works somewhat strangely:

System.out.println(new proba().fun(0)); // compiles, prints true
System.out.println(new proba().fun(0.0)); // compiles, prints false
System.out.println(new proba().fun(new Integer(0))); // compiles, prints false

That's why Java-7 promotes 0 to Integer object (via autoboxing), then compares two objects by reference which is unlikely what you want.

To fix your code, you may convert Number to some predefined primitive type like double:

boolean fun(Number n) {
    return n == null || 0 == n.doubleValue();
}
like image 108
Tagir Valeev Avatar answered Dec 23 '22 11:12

Tagir Valeev


If you want to compare Number and int - call Number.intValue() and then compare.

like image 34
eg04lt3r Avatar answered Dec 23 '22 11:12

eg04lt3r