What code does the compiler generate for autoboxing?
Asked Answered
C

4

32

When the Java compiler autoboxes a primitive to the wrapper class, what code does it generate behind the scenes? I imagine it calls:

  • The valueOf() method on the wrapper
  • The wrapper's constructor
  • Some other magic?
Crunode answered 3/1, 2009 at 5:32 Comment(0)
W
49

You can use the javap tool to see for yourself. Compile the following code:

public class AutoboxingTest
{
    public static void main(String []args)
    {
        Integer a = 3;
        int b = a;
    }
}

To compile and disassemble:

javac AutoboxingTest.java
javap -c AutoboxingTest

The output is:

Compiled from "AutoboxingTest.java"
public class AutoboxingTest extends java.lang.Object{
public AutoboxingTest();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_3
   1:   invokestatic    #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
   4:   astore_1
   5:   aload_1
   6:   invokevirtual   #3; //Method java/lang/Integer.intValue:()I
   9:   istore_2
   10:  return

}

Thus, as you can see, autoboxing invokes the static method Integer.valueOf(), and autounboxing invokes intValue() on the given Integer object. There's nothing else, really - it's just syntactic sugar.

Weywadt answered 3/1, 2009 at 5:40 Comment(4)
It's interesting to note that it calls valueOf(int) instead of new Integer(int) to convert int to Integer. valueOf does object caching for the first 1000 or so integers.Peerless
@Craig: to be precise, -128 to 127 must be cached, other values may be cached by an implementation.Uxorial
Also worth noting that the compiler doesn't have to use Integer.valueOf - the language specification only requires that a.intValue() == 3. docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7Smokechaser
@PaŭloEbermann To be even more precise, you can't redefine the lower bound of the cache (except with some dirty hacks) : #29633658Truman
C
10

I came up with a unit test that proves that Integer.valueOf() is called instead of the wrapper's constructor.

import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;

import org.junit.Test;

public class Boxing {
    @Test
    public void boxing() {
        assertSame(5, 5);
        assertNotSame(1000, 1000);
    }
}
Crunode answered 4/1, 2009 at 7:21 Comment(0)
C
4

If you look up the API doc for Integer#valueOf(int), you'll see it was added in JDK 1.5. All the wrapper types (that didn't already have them) had similar methods added to support autoboxing. For certain types there is an additional requirement, as described in the JLS:

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. §5.1.7

It's interesting to note that longs aren't subject to the same requirement, although Long values in the -128..127 range are cached in Sun's implementation, just like the other integral types.

I also just discovered that in my copy of The Java Programming Language, it says char values from \u0000 to \u00ff are cached, but of course the upper limit per the spec is \u007f (and the Sun JDK conforms to the spec in this case).

California answered 4/1, 2009 at 8:44 Comment(0)
M
1

I'd recommend getting something like jad and decompiling code a lot. You can learn quite a bit about what java's actually doing.

Modulus answered 3/1, 2009 at 6:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.