Frage

In Java ist dies der Fall:

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

Was ich frage mich, ist dies: Ist die Tatsache, dass x auf den Umfang der if-Anweisung beschränkt ist nur ein Merkmal der Java-Compiler, oder x tatsächlich aus dem Stapel nach der if-Anweisung entfernt

War es hilfreich?

Lösung

Nein, Codeblöcke keinen separaten Stapelrahmen erhalten, ist die Verwendung des einen der umgebenden Methode.

Sobald jedoch ein Variable Blätter Umfang, seinen Platz in dem aktuellen Stack-Frame kann für andere Variablen wiederverwendet werden.

Die Struktur und die Verwendung eines Stapelrahmens ist in der Java Virtual Machine Specification § 3.6 Frames :

  

Ein neuer Rahmen wird jedes Mal erstellt eine Methode aufgerufen wird. Ein Rahmen wird zerstört, wenn ihr Methodenaufruf abgeschlossen ist, ob diese Beendigung normal ist oder abrupt (er eine abgefangene Ausnahme auslöst).

Dies gibt auf jeden Fall ein. 1: 1-Beziehung zwischen Aufrufen von Prozeduren und Rahmen

Andere Tipps

Blocks sind ein Teil der Java-Sprache (die eine strukturierten Programmiersprache ), während sie nicht Teil des kompilierten Bytecode sind (was ein nicht-strukturierte Sprache ).

Eine Methode Spezifikation in einer Klassendatei gibt an, wie viele lokale Variablen verwendet das Verfahren insgesamt oberhalb der eigentlichen Liste von Anweisungen. Aber wo die Blöcke einmal, wo in dem Java-Code können nicht aus dem Bytecode abgeleitet werden.

Vor allem in den Bytecode-Variablen werden in den variablen Slots und variable Schlitze gespeichert und nicht auf den Stapel. Der Schlitz durch eine andere Variable wiederverwendet werden könnte, aber es ist nicht garantiert, dass Wert aus dem variablen Schlitz entfernt werden würde.

Zum Beispiel kann die folgende Klasse

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

wird in diesen Bytecode kompiliert:

// 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
}

Hinweis, daß die Variable in Zeile erstellt x 7 in die variable Steckplatz 2 gespeichert wird, der noch an der Bytecode verfügbar ist, entsprechend Leitung 10.

Es gibt keine Angaben darüber, wie der Java-Sprache in den Bytecode andere dann einige Beispiele zusammengestellt werden müssen, wie man richtig einige Sprachkonstrukte kompilieren. Allerdings ist Java-Compiler nicht verwendeten Variablen zu eliminieren erlaubt. Z.B. wenn x zugewiesen wurden, aber nicht überall verwendet wird, ist Compiler erlaubt, dass Code fallen. In ähnlicher Weise Compiler alle die statischen Konstanten inlining.

Ja, es ist wirklich vom Stapel machen den Schlitz entfernt wird, vorher besetzt durch ‚x‘ wiederverwendbar durch eine andere lokale Variable.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top