質問

Javaではこれが事実です:

public void method() {
  if (condition) {
    Object x = ....;
  }
  System.out.println(x); // Error: x unavailable
}

私が疑問に思っているのはこれだと思っています: x の範囲に限定されています if- ステートメントJavaコンパイラの機能、または x 実際にスタックから削除されました if-声明?

役に立ちましたか?

解決

いいえ、コードブロックは個別のスタックフレームを取得しません。周囲のメソッドの使用を使用します。

ただし、変数がスコープを離れると、現在のスタックフレーム内の場所を他の変数に対して再利用できます。

スタックフレームの構造と使用は、 Java仮想マシン仕様§3.6フレーム:

メソッドが呼び出されるたびに新しいフレームが作成されます。その完了が正常であろうと突然であろうと、メソッドの呼び出しが完了するとフレームが破壊されます(猛攻撃の例外がスローされます)。

これは、メソッドの呼び出しとフレームの間の1:1の関係を間違いなく指定します。

他のヒント

ブロックはJava言語の一部です(これは 構造化されたプログラミング言語)それらはコンパイルされたbytecodeの一部ではありませんが(これは 非構造 言語).

クラスファイルのメソッド仕様は、実際の命令リストより上に、メソッドが合計で使用するローカル変数の数を指定します。ただし、JavaコードのブロックがBytecodeから推測できない場合。

まず、バイトコードの変数は、スタックではなく変数スロットと変数スロットに保存されます。スロットは別の変数によって再利用できますが、変数スロットから値が削除されることは保証されていません。

たとえば、次のクラス

  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);
    }
  }

このbytecodeにコンパイルされています。

// 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が割り当てられているがどこにも使用されていない場合、コンパイラはそのコードをドロップすることが許可されています。同様に、コンパイラはすべての静的定数をインラリングしています。

はい、それは本当にスタックから削除され、以前に「x」が再利用できるスロットが他のローカル変数によって再利用可能になります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top