Adding to what has been said, whenever you are confused about what the compiler does under the hood to your code, what I usually do and recommend, is to write a minimal example, compile it, then use a decompiler to check how the compiler manipulated the class
files. You could then see the compiler actually translates your code to:
public Integer getAnInt() {
int[] var1 = new int[]{4};
return Integer.valueOf(var1[0]);
}
Technically, you asked the compiler to use autoboxing when you put Integer
as the return type. It should not matter what happens to the value after it is returned, but for optimization reasons, a JIT compiler can avoid this behavior, as was already stated.
Here's my flow to decompile:
- Compile your
java
file with javac
. I do this in the command line.
- Either download a decompiler in your system or find one online. I use javadecompilers which is very easy to use and has the advantage of having multiple decompilers available to try.
- Add your resulting
class
file to it and wait to generate the source code. You may choose to try a different decompiler as each can differ a bit in the output generated. I used FernFlower to decompile your example.
Note: A disadvantage to the online version is that if your code has multiple classes,javac
will generate separate class
file for each. You can choose either to add only the class
file that you are interested to the decompiler (a minimal example should not have more than a few classes anyway and most of the time you'll be interested in decompiling the bytecode of a certain class
) - or - you can either choose to create a jar
with all of class
files and search for a decompiler capable of decompiling entire jar
files. I prefer adding the class
files directly.
Lastly, don't forget the Java Disassembler javap
always available in the Java SDK. Using -c
prints out the disassembled code - the instructions that comprises the Java bytecode - for each of the methods in the class. These are documented in the JVM Specification. You can understand some on the spot because method invocations to the Java standard library are marked in comments:
public static java.lang.Integer getAnInt();
Code:
0: iconst_1
1: newarray int
3: dup
4: iconst_0
5: iconst_4
6: iastore
7: astore_0
8: aload_0
9: iconst_0
10: iaload
11: invokestatic #7 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
14: areturn
A nice way to check that Integer.valueOf
gets called in your code.
Integer
anyway. You should return anint
and let autoboxing promote it to anInteger
if needed. – GingergingerbreadInteger
, say if you implement a generic interfaceContainer<Integer>
, whereContainer<T>
has aT
-bearingget
method, thenget
would have to returnInteger
. (Maybe yoy meant "In general, you should prefer returningint
", which would have been true.) – Holocaust