0

I'm curious as to why the following line works fine in IntelliJ but is shown as an error in Eclipse (both using Java 7):

return toolbar.getClientProperty("PrototypeToolbar") == true;

I saw this code as part of our project and at first I did not think it would work because getClientProperty() returns an Object and we are comparing it to a boolean. However, for those of us that use IntelliJ, it works fine but for others on the team that are using Eclipse, it shows as an error.

My guess is that it can technically work because 0 == false and it could be that anything not 0 == true. However, I'm not sure why one IDE complains and the other does not. Which one is 'right'?

Note: The above line was used to find a toolbar that was part of an old framework and difficult to access. This check was used to filter and find the PrototypeToolbar. I've already suggested to change this from just simply checking if it's true to checking the type using instanceof.

Thanks!

Abubakr
  • 312
  • 2
  • 14
  • @SotiriosDelimanolis: Well, it compiles for me using javac... I believe it just boxes the `true` and performs normal reference comparison. – Jon Skeet Jan 05 '16 at 17:10
  • @JonSkeet _It is a compile-time error if it is impossible to convert the type of either operand to the type of the other by a casting conversion (§5.5). The run-time values of the two operands would necessarily be unequal (ignoring the case where both values are null)._ Maybe... – Sotirios Delimanolis Jan 05 '16 at 17:11
  • @SotiriosDelimanolis: Well you *can* convert `true` to `Object` by casting... – Jon Skeet Jan 05 '16 at 17:13
  • @JonSkeet Yeah, that's what I mean. – Sotirios Delimanolis Jan 05 '16 at 17:15
  • Although I've now found it *not* compiling with a different version of javac. Maybe this is a 1.7 vs 1.8 difference... – Jon Skeet Jan 05 '16 at 17:15
  • I just tried in IntelliJ (for Java 8) and it shows as an error. Seems likely that it is related to Java version. – khelwood Jan 05 '16 at 17:16
  • 1
    @SotiriosDelimanolis: Good call. Done. – Jon Skeet Jan 05 '16 at 18:03
  • It shows an error in IntelliJ with 1.6 for us but not 1.7 as well. So originally we though maybe Eclipse wasn't set to 1.7, but it was. – Abubakr Jan 05 '16 at 18:42

1 Answers1

3

It looks like this was valid code under javac 1.7, but isn't under 1.8. I suspect it's a bug fix in javac.

This isn't treating 0 as false and anything non-0 as true. It's effectively doing this:

Object wrapped = true; // Autoboxing
return toolbar.getClientProperty("PrototypeToolbar") == wrapped;

That will only return true if toolbar.getClientProperty(...) returns the same reference - e.g. if it's boxed the value true as well, or explicitly called Boolean.valueOf(true).

Sample:

// Compiles under 1.7 but not 1.8
public class Test {
    public static void main (String args[]) {
        Object x = Boolean.valueOf(true);
        Object y = new Boolean(true);
        System.out.println(x == true); // Prints true
        System.out.println(y == true); // Prints false
    }
}

I suspect your code should be refactored to:

return Boolean.TRUE.equals(toolbar.getClientProperty("PrototypeToolbar"));

That will return false if getClientProperty() returns a non-Boolean reference, or null, or false.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194