views:

218

answers:

5
+12  Q: 

Weird Java Boxing

(Sorry if this is a duplicate, I have no idea how I would even search for this)

I just saw code similar to this:

public class Scratch
{
    public static void main(String[] args)
    {
        Integer a = 1000, b = 1000;
        System.out.println(a == b);

        Integer c = 100, d = 100;
        System.out.println(c == d);
    }
}

When ran, this block of code will print out:

false
true

I understand why the first is false: because the two objects are separate objects, so the == compares the references. But I can't figure out, why is the second statement returning true? Is there some strange autoboxing rule that kicks in when an Integer's value is in a certain range? What's going on here?

Thanks

+3  A: 

Integer objects in some range (I think maybe -128 through 127) get cached and re-used. Integers outside that range get a new object each time.

Adam Crume
+2  A: 

My guess is that Java keeps a cache of small integers that are already 'boxed' because they are so very common and it saves a heck of a lot of time to re-use an existing object than to create a new one.

Omnifarious
+3  A: 

Yes, there is a strange autoboxing rule that kicks in when the values are in a certain range. When you assign a constant to an Object variable, nothing in the language definition says a new object must be created. It may reuse an existing object from cache.

In fact, the JVM will usually store a cache of small Integers for this purpose, as well as values such as Boolean.TRUE and Boolean.FALSE.

Avi
+15  A: 

The true line is actually guaranteed by the language specification. From section 5.1.7:

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

The discussion goes on, suggesting that although your second line of output is guaranteed, the first isn't (see the last paragraph quoted below):

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 characters and shorts, as well as integers and longs in the range of -32K - +32K.

Jon Skeet
It may also be worth noting that autoboxing is actually just syntactic sugar for calling the `valueOf` method of the box class (like [`Integer.valueOf(int)`](http://java.sun.com/javase/6/docs/api/java/lang/Integer.html#valueOf%28int%29)). Interesting that the JLS defines the exact unboxing desugaring - using `intValue()` et al - but not the boxing desugaring.
gustafc
A: 

In Java the boxing works in the range between -128 and 127 for an Integer. When you are using numbers in this range you can compare it with the == operator. For Integer objects outside the range you have to use equals.

marvin