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 typeSuch 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.`long`

or type`double`

occupies two consecutive local variables.

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.