Question

I have stumbled upon this in Java (JDK 1.7):

    Integer a = 100;
    Integer b = 100;
    Integer c = 1000;
    Integer d = 1000;

    System.out.println(a == b); //true
    System.out.println(c == d); //false
    System.out.println(new Integer(100) == new Integer(100)); //false
    System.out.println(new Integer(1000) == new Integer(1000)); //false

The output is: true false false false

Why does a==b evaluate to true? What is the reason for this? Is this similar to String internalization?

Was it helpful?

Solution

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.)

OTHER TIPS

This is because all small integers are cached (like for String internalization), so you get the same instance when you boxe them.

From the specification :

If the value p being boxed is true, false, a byte, or a char in the range \u0000 to \u007f, or an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.

And the additional notes enlighten on the compromise that was made :

Ideally, boxing a given primitive value p, would always yield an identical reference. In practice, this may not be feasible using existing implementation techniques. The rules above are a pragmatic compromise. The final clause above requires that certain common values always be boxed into indistinguishable objects. The implementation may cache these, lazily or eagerly. For other values, this formulation disallows any assumptions about the identity of the boxed values on the programmer's part. This would allow (but not require) sharing of some or all of these references.

This ensures that in most common cases, the behavior will be the desired one, without imposing an undue performance penalty, especially on small devices. Less memory-limited implementations might, for example, cache all char and short values, as well as int and long values in the range of -32K to +32K.

values from -128 to 127 are cached

java.lang.Integer has a inner static class that caches all Integer objects between -128 and 127

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top