44

I had this question in my Java test where I had to assign values to a and b so this expression evaluates to true:

(a<=b && b<=a && a!=b)

Sadly, I had no idea what the answer was.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jhonny
  • 587
  • 1
  • 6
  • 17
  • 3
    What are the types of `a` and `b`? – Tunaki Sep 24 '15 at 10:53
  • 1
    `a` and 'b' can be any number wrapper as long as they are the same. `Byte`, `Character` `Integer`, `Long`, `Float`, `Double` as `!=` compares references but `<=` compares the unboxed values. – Peter Lawrey Sep 24 '15 at 14:14
  • 1
    If you like this puzzle, try `x != x + 0` has three possible types, and `x == -x` has 22 possible values/types. – Peter Lawrey Sep 24 '15 at 14:16
  • Only three for the last one? You're probably thinking that a `float` or `double` equal to NaN will use broken IEEE-754 equality, and a string will do a reference comparison between itself and a new string which has a '0' at the end. Wouldn't any non-null value of any of the wrapper types work, though? – supercat Sep 24 '15 at 22:28
  • 2
    What a horrible test question. Hope it was an advanced subject. – WW. Sep 25 '15 at 02:16

1 Answers1

78

There's a simple trick here.

You cannot think this through with boolean logic only. Using that, this combination...

  • a is less than or equal to b, and
  • b is less than or equal to a, and
  • a is not equal to b

...would never return true.

However, the != operator compares references if its operands are objects.

So, the following will return true:

Integer a = 1;
Integer b = new Integer(1);
System.out.println(a<=b && b<=a && a!=b);

What happens here is: a as an object reference is not equal to b as an object reference, although of course they hold equal integer values.

underscore_d
  • 6,309
  • 3
  • 38
  • 64
Mena
  • 47,782
  • 11
  • 87
  • 106
  • This assumes that `Integer` is never `intern`ed - which is a fair assumption for the higher values but some JVMs cache `-127 - 128`. You may be better to use `10000` or something. – OldCurmudgeon Sep 24 '15 at 11:03
  • 15
    @OldCurmudgeon - He is using `new Integer(1);` which doesn't return values from local cache (unlike `Integer.valueOf()` ) . So it is fine i guess :) – TheLostMind Sep 24 '15 at 11:03
  • 3
    @OldCurmudgeon was about to answer but ThwLostMind beat me to it. Explicitly initializing a `new Integer(int value)` defiles interning. – Mena Sep 24 '15 at 11:05
  • 1
    You absolutely can think this through Boolean logic (only not solely using it). Equality/inequality operators have nothing to do with the conjugations part. – mike3996 Sep 24 '15 at 12:25
  • 2
    I tried to find a passage in the JLS which guarantees that this works, but I haven't had any luck … nor have I been able to determine that it *doesn't*. Anybody have a quote? – Jörg W Mittag Sep 24 '15 at 13:12
  • 3
    @JörgWMittag See [15.20.1](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.20.1): *"...operands ...must be...convertible to a primitive numeric type"* for `<=` and `>=`, and [15.21.3](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.21.3), *"... result of == is true if ... both refer to the same object"* for `==` – Marco13 Sep 24 '15 at 13:49
  • I feel dirty upvoting this answer, because the question (not the OP's, but the question on the test) is so... icky. It's a brainteaser that's a fun gotcha, and possibly a neat way to see if someone can "think outside the box," but probably a pretty poor test of someone's Java knowledge. – yshavit Sep 24 '15 at 17:12
  • 2
    @yshavit I have to disagree with you here. This *looks* like a fun trick, but it also implies being aware of some fundamentals of the Java language few people bother to investigate - here, `Number` wrapper classes, caching and object equality. I wouldn't be surprised to find questions like this in Oracle's 1Z0-804 exam for instance. – Mena Sep 24 '15 at 17:36
  • 7
    @Mena Knowledge of those things is necessary but not sufficient to answer this question, especially given that it depends on behavior that's generally frowned upon (comparing references using `!=`). If I showed somebody the answer and asked them to spot the bug, I would very much expect them to find it; but going the other way around, of presenting seemingly-buggy behavior and asking someone to create the bad code that triggers it... that seems less useful to me. YMMV, I guess. :) – yshavit Sep 24 '15 at 18:11
  • This feels as evil as [this](http://codegolf.stackexchange.com/a/28818/21697)... *slow clap* – h.j.k. Sep 25 '15 at 07:39
  • @h.j.k. nice one! Still laughing... pranks ahoy! :D – Mena Sep 25 '15 at 08:25