Domanda

In Java questo è il caso:

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

Quello che mi chiedo è questo:È il fatto che x è limitato all'ambito del if-statement è solo una funzionalità del compilatore Java, o lo è x effettivamente rimosso dallo stack dopo il if-dichiarazione?

È stato utile?

Soluzione

No, blocchi di codice non si ottiene uno stack frame separato, l'uso quella del metodo circostante.

Tuttavia, una volta portata foglie variabile, esso è posto nella stack frame corrente può essere riutilizzato per altre variabili.

La struttura e l'uso di uno stack frame è descritta nella Java Virtual Machine Specification § 3.6 Frames :

  

Un nuovo telaio viene creata ogni volta che un metodo viene richiamato. Un frame viene distrutta quando i suoi Completa metodo di chiamata, se tale termine è normale o brusca (si getta un'eccezione non rilevata).

Questa specifica sicuramente un 1:. Relazione tra 1 chiamate di metodo e cornici

Altri suggerimenti

I blocchi fanno parte del linguaggio Java (che è a linguaggio di programmazione strutturato) mentre non fanno parte del bytecode compilato (che è un non strutturato lingua).

Una specifica del metodo in un file di classe specifica quante variabili locali il metodo utilizza in totale, sopra l'effettivo elenco di istruzioni.Ma dove i blocchi una volta si trovavano nel codice Java non possono essere dedotti dal bytecode.

Prima di tutto, nelle variabili bytecode vengono memorizzati nelle fessure variabili e slot di variabili e non in pila. Lo slot potrebbe essere riutilizzato da un'altra variabile, ma non è garantito che il valore sarebbe stato rimosso dalla fessura variabile.

Ad esempio, la seguente classe

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

viene compilato in bytecode questo:

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

Si noti che variabile X creato alla riga 7 è memorizzato nella fessura variabile 2, che è ancora disponibile presso il bytecode corrispondente alla linea 10.

Non v'è alcuna specifica su come linguaggio Java deve essere compilato in bytecode altri poi alcuni esempi come compilare correttamente alcuni costrutti del linguaggio. Tuttavia compilatore Java è permesso di eliminare le variabili non utilizzate. Per esempio. se x sono stati assegnati, ma non utilizzati ovunque, compilatore è permesso di abbandonare quel codice. Allo stesso modo, il compilatore è messa in linea tutte le costanti statiche.

Sì, è davvero rimossa dalla pila rendendo slot precedentemente occupato da 'x' riutilizzabile da un altro variabile locale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top