tmn
tmn

Reputation: 11559

Java autoboxing and mathematical expressions?

I think when I read Joshua Bloch's Effective Java, I got the impression that autoboxing should be avoided for performance reasons. But I'm getting conflicting information that I can trust the compiler to use valueOf() and intValue() optimally when I do implicit conversion.

So this code I composed below

Integer capacity = 50103;
Integer inventory = 40122;

int available = capacity - inventory;  

Theoretically will compile to the same bytecode as the code below.

Integer capacity = Integer.valueOf(50103);
Integer inventory = Integer.valueOf(40122);

int available = capacity.intValue() – inventory.intValue();

Is this true as of Java 7 and 8? Is there any reason to explicitly box/unbox or will the compiler optimize for that now?

Upvotes: 3

Views: 155

Answers (2)

meriton
meriton

Reputation: 70564

that autoboxing should be avoided for performance reasons

This simply means that boxing and unboxing incurs an overhead, and should not be performed needlessly.

It does not matter whether boxing/unboxing is performed implicitly or explicitly; it compiles to the same byte code either way.

Upvotes: 2

Tunaki
Tunaki

Reputation: 137064

This is not an optimization, it's just the same code, written differently but compiled to the same byte-code.

With the following:

Integer capacity = 50103;
Integer inventory = 40122;
int available = capacity - inventory;  

both integers value are first boxed into an Integer. Then they are unboxed to int to perform the subtraction. This is completely equivalent to the second snippet of code.

There is no particular reason to explicitely box the values in those cases. It is best to leave the compiler do that because it provides a shorter, more readable code.

This is the byte-code produced with your first example (JDK 1.8.0_60):

 0: ldc           #2      // int 50103
 2: invokestatic  #3      // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
 5: astore_1
 6: ldc           #4      // int 40122
 8: invokestatic  #3      // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
11: astore_2
12: aload_1
13: invokevirtual #5      // Method java/lang/Integer.intValue:()I
16: aload_2
17: invokevirtual #5      // Method java/lang/Integer.intValue:()I
20: isub
21: istore_3
22: getstatic     #6      // Field java/lang/System.out:Ljava/io/PrintStream;
25: iload_3
26: invokevirtual #7      // Method java/io/PrintStream.println:(I)V
29: return

where you can clearly see that the first snippet was compiled to the same as the second snippet.

Upvotes: 6

Related Questions