I have this very simple class
public class TestImpl2 { public TestImpl2() { } public double run(double param) { double d = 7.0D; double k = 4.0D; if (param < k) { System.out.println(d); } return 0.0D; } }
That i compiled with javac and then decompiled with javap to see its bytecode.
0: ldc2_w #14 // double 7.0d 3: dstore_3 4: ldc2_w #16 // double 4.0d 7: dstore 5 9: dload_1 10: dload 5 12: dcmpg 13: ifge 23 16: getstatic #23 // Field java/lang/System.out:Ljava/io/PrintStream; 19: dload_3 20: invokevirtual #29 // Method java/io/PrintStream.println:(D)V 23: dconst_0 24: dreturn
Lets check offsets
0 – is reserved for “this” reference
1 – is the method parameter
2 – skipped ?
3 – variable “d”
4 – skipped ?
5 – variable “k”
Why were offsets 2 and 4 skipped? Is it because method param, d and k are doubles or is it something completly else?
Advertisement
Answer
According to the JVM spec (emphasis mine):
Local variables are addressed by indexing. The index of the first local variable is zero. An integer is considered to be an index into the local variable array if and only if that integer is between zero and one less than the size of the local variable array.
A value of type
long
or typedouble
occupies two consecutive local variables. Such a value may only be addressed using the lesser index. For example, a value of type double stored in the local variable array at index n actually occupies the local variables with indices n and n+1; however, the local variable at index n+1 cannot be loaded from.
It is not that indices 2 and 4 are not used. It’s just that param
and d
are double
s and they occupy 2 spaces each.