まず、バイトコードでは、変数はスタックではなく、変数スロットと変数スロットに格納されます。スロットは別の変数で再利用できますが、変数スロットから値が削除される保証はありません。
たとえば、次のクラス
public class A {
public void method(boolean condition) {
6 if (condition) {
7 Object x = "";
8 System.out.println(x);
9 }
10 System.out.println(condition);
}
}
このバイトコードにコンパイルされます:
// class version 50.0 (50)
public class A {
...
// access flags 0x1
public method(Z)V
L0
LINENUMBER 6 L0
ILOAD 1
IFEQ L1
L2
LINENUMBER 7 L2
LDC ""
ASTORE 2
L3
LINENUMBER 8 L3
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
ALOAD 2
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V
L1
LINENUMBER 10 L1
FRAME SAME
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
ILOAD 1
INVOKEVIRTUAL java/io/PrintStream.println (Z)V
L4
LINENUMBER 11 L4
RETURN
L5
LOCALVARIABLE this LA; L0 L5 0
LOCALVARIABLE condition Z L0 L5 1
LOCALVARIABLE x Ljava/lang/Object; L3 L1 2
MAXSTACK = 2
MAXLOCALS = 3
}
7行目で作成された変数xは、10行目に対応するバイトコードで引き続き使用可能な変数スロット2に格納されていることに注意してください。
Java言語をバイトコードにコンパイルする方法についての仕様はありませんが、いくつかの言語構造を適切にコンパイルする方法の例がいくつかあります。ただし、Javaコンパイラは未使用の変数を削除できます。たとえば、xが割り当てられているが、どこでも使用されていない場合、コンパイラはそのコードを削除できます。同様に、コンパイラはすべての静的定数をインライン化します。