1

There's a presentation on AutoValue (a terse way to define immutable objects in Java, with sensible defaults for equals, hashCode, etc.): https://docs.google.com/presentation/d/14u_h-lMn7f1rXE1nDiLX0azS3IkgjGl5uxp5jGJ75RE/edit#slide=id.g2a5e9c4a8_047

In the beginning, they go over some alternatives to AutoValue. Obviously, one alternative is a POJO coded by hand. They warn about this POJO being unexpectedly hard to change.

I've transcribed the slide here:

Are changes really that risky?

Suppose a required int field becomes optional. You change

int number;

to

Integer number;

Tests still pass... and everything's fine... until one day, objects put into Sets start mysteriously "disappearing" from the set! Why? (Left as an exercise to the reader.)

I can't figure out this "exercise". What kind of "disappearing"? contains(element) is unexpectedly false? size() decrements without remove()? iterator() doesn't include the element anymore? And why would any of these happen?

Vanessa Phipps
  • 2,205
  • 1
  • 18
  • 22
  • All `int` comparisons using `==` would start to fail for values > 127 (the `Integer` values 0-127 are cached). Not sure how that would affect sets, since you can't put primitives in a `Set`, they get boxed. I suppose if the `int` member was used in `equals()` implementations of other classes that are placed into sets. But it all boils down to `==` not working as expected for non-cached values. – Jim Garrison Dec 13 '17 at 19:56
  • @JimGarrison Your understanding is correct. The one thing that is missing here however is that the context that the author implies is connected not with putting primitives into sets as it is not possible of course, but that this field is used along with the other fields in this class. And therefore as it originally was primitive and used ==, changing the type will still work "thanks" to auto-boxing, but as you mentioned will be broken. – kasur Jun 07 '18 at 19:32

1 Answers1

4

AFAIK the main thing that would break is equals, because this.number == obj.number has unexpected results when number is an Integer.

That would affect contains as well as remove (both unexpectedly false), I think.

I'm still a bit green with Java though, so if anyone has other comments or answers, I'd appreciate it. Mostly, I don't think size or iterator would be affected, so presumably the element would still show up in debuggers that use iterator or some fancier way of getting the contents. That doesn't sound much like "disappearing" to me so I'd like to know if I'm missing anything.

Vanessa Phipps
  • 2,205
  • 1
  • 18
  • 22