Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 275
tmn Avatar asked Mar 06 '26 15:03

tmn


1 Answers

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.

like image 192
Tunaki Avatar answered Mar 08 '26 03:03

Tunaki