Pregunta

En Java este es el caso:

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

Lo que me pregunto es: ¿Es el hecho de que x se limita al ámbito de la if-declaración sólo una característica del compilador de Java, o se x realidad elimina de la pila después de la declaración-if

¿Fue útil?

Solución

No, bloques de código no recibe un marco de pila separada, el uso del método de una de las rodea.

Sin embargo, una vez al alcance hojas variables, de lugar en el marco de pila actual se puede reutilizar para otras variables.

La estructura y el uso de un marco de pila se describe en el Java virtual Machine Especificación § 3.6 Marcos :

  

una nueva trama se crea cada vez que se invoca un método. Un marco se destruye cuando sus ultima invocación de método, ya sea que la terminación es normal o brusca (lanza una excepción no detectada).

Esto definitivamente especifica un 1:. Relación 1 entre invocaciones de métodos y marcos

Otros consejos

Los bloques son una parte del lenguaje Java (que es un lenguaje de programación estructurado ), mientras que no son una parte del código de bytes compilado (que es un no estructurada idioma).

Una especificación de método en un archivo de clase especifica el número de variables que utiliza el método de los en total, por encima de la lista real de las instrucciones locales. Pero donde los bloques de una vez en qué parte del código de Java no pueden inferirse a partir del código de bytes.

En primer lugar, en las variables de código de bytes se almacenan en las ranuras y las ranuras de variables variables y no en la pila. La ranura podría ser reutilizado por otra variable, pero no se garantiza que el valor sería eliminado de la ranura variable.

Por ejemplo, la siguiente clase

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

se compila en este código de bytes:

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

Tenga en cuenta que la variable X creado en la línea 7 se almacena en la ranura variable de 2, que todavía está disponible en el código de bytes correspondiente a la línea 10.

No hay ninguna especificación sobre cómo el lenguaje Java tiene que ser compilado en el código de bytes otras continuación algunos ejemplos de cómo compile correctamente algunas construcciones del lenguaje. Sin embargo se permite compilador de Java para eliminar las variables no utilizadas. P.ej. si se cedieron x, pero no se utilizan en cualquier lugar, se permite que el compilador para dejar ese código. Del mismo modo, el compilador se Inlining todas las constantes estáticas.

Sí, realmente se elimina de la pila haciendo que la ranura ocupada previamente por 'x' reutilizable por alguna otra variable local.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top