Is this similar to String internalization?
Yes - essentially all integers that can fit in a byte (-128 to +127) are interned and thus share the same underlying object. Larger ones aren't, and thus probably don't share the same underlying object (this is covered in JLS 5.1.7) - though note that there's nothing in the spec that prevents larger integers sharing the same underlying object if someone were to choose to implement a VM that way.
I would imagine the rationale is that "smaller" integers in this range are used much more often than larger ones, so using the same underlying objects is worth it to reduce the potential memory footprint.
In your new Integer(100) == new Integer(100)
example, this isn't the case since you're explicitly creating new integer objects, similar to how new String("hi") == new String("hi")
evaluates to false.
Just to re-iterate - when comparing integers like this in all real world scenarios, then .equals()
should be used (or preferably still, == with primitive integers unless there's a good case for using the object type.)