Comment by sedro

Comment by sedro 3 days ago

17 replies

Autoboxing's evil twin, auto-unboxing should knock the score down a few points.

  Integer a = null;
  int b = 42;
  if (a == b) {} // throws NullPointerException
dcminter 3 days ago

Or my favourite...

  Short w = 42;
  Short x = 42;
  out.println(w == x); // true
  Short y = 1042;
  Short z = 1042;
  out.println(y == z); // false
  • prein 3 days ago

    Once, after we had an application go live, we started getting reports after a few hours that new users were unable to log in.

    It turns out, somewhere in the auth path, a dev had used `==` to verify a user's ID, which worked for Longs under (I believe) 128, so any users with an ID bigger than that were unable to log in due to the comparison failing.

  • kittko 2 days ago

    I’ll bite. Why does this not work as you’d expect?

    • dcminter 2 days ago

      I'm comparing object references (pointers) not the value boxed by the object (what the pointer points to).

      For performance reasons boxed Short objects are interned when they represent values in the range -127 to +128 so for 42 the pointers will point to the same interned object after 42 is autoboxed to a Short. Whereas 1042 is outside this interning range and the autoboxing creates two distinct objects with different pointers.

      It's very simple but (a) non-obvious if you don't know about it and (b) rather wordy when I spell it out like this :)

      In general in Java you want obj.equals(other) when dealing with objects and == only with primitives, but autoboxing/unboxing can cause confusion about which one is dealing with.

      In other other words, the surprise ought to be that w == x is true, not that y == z is false!

  • sedro 3 days ago

    That's another gotcha-- interning of strings and boxed primitives.

    Are there linters for this sort of thing? I don't write Java much any more.

    • dcminter 3 days ago

      > Are there linters for this sort of thing?

      Yes and they're pretty good so it's rarely an issue in practice. Using == on object references will indeed usually get you yelled at by the linter.

      • MBCook 3 days ago

        I’ll say from experience that even if your IDE highlights that by default people won’t pay any attention to it and the bug will get in.

        I’ll be happy when it’s fixed.

  • hashmash 3 days ago

    If JEP 401 is ever delivered (Value Classes and Objects), then this sort of problem should go away.

    • mrkeen 2 days ago

      Do Java problems go away? I thought the selling point was that your huge un-rewritable enterprise software will crash tomorrow like it crashed yesterday.

[removed] 3 days ago
[deleted]
commandersaki 3 days ago

I'm not much of a PL nerd, what should it do?

  • blandflakes 2 days ago

    Return false! They aren't equal. But of course we're comparing a reference to a primitive, so we either lift the primitive to a reference, or lower the reference... so here we are.

  • mrkeen 2 days ago

    Fail to compile when you assign something which isn't an integer to an integer.

    • michaelcampbell 2 days ago

      None of that code does that; the "issue" is with `==` between an int and an Integer. I'd accept a failure to compile _that_, but that does kind of kill the utility of the 99.9% of times where auto-boxing and unboxing is syntactically simpler.