Pergunta

Em Java é o caso:

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

O que estou me perguntando é o seguinte:É o fato de que x está limitado ao âmbito do if-statement é apenas um recurso do compilador Java ou é x realmente removido da pilha após o if-declaração?

Foi útil?

Solução

Não, os blocos de código não recebem um quadro de pilha separado, o uso do método circundante.

No entanto, uma vez que uma variável deixa o escopo, é o lugar no quadro da pilha atual pode ser reutilizado para outras variáveis.

A estrutura e o uso de um quadro de pilha são descritos no Especificação da máquina virtual Java § 3.6 quadros:

Um novo quadro é criado sempre que um método é chamado. Um quadro é destruído quando a sua invocação de método é concluída, seja essa conclusão normal ou abrupta (lança uma exceção não capturada).

Isso definitivamente especifica uma relação 1: 1 entre invocações e quadros de métodos.

Outras dicas

Os blocos fazem parte da linguagem Java (que é uma linguagem de programação estruturada) embora não façam parte do bytecode compilado (que é um não estruturado linguagem).

Uma especificação de método em um arquivo de classe especifica quantas variáveis ​​locais o método usa no total, acima da lista real de instruções.Mas onde os blocos uma vez estão no código Java não podem ser inferidos a partir do bytecode.

Em primeiro lugar, no bytecode as variáveis ​​são armazenadas nos slots de variáveis ​​e nos slots de variáveis ​​e não na pilha.O slot pode ser reutilizado por outra variável, mas não é garantido que o valor seja removido do slot da variável.

Por exemplo, a seguinte 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);
    }
  }

é compilado neste 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
}

Observe que a variável x criada na linha 7 é armazenada no slot de variável 2, que ainda está disponível no bytecode correspondente à linha 10.

Não há nenhuma especificação sobre como a linguagem Java deve ser compilada no bytecode, além de alguns exemplos de como compilar corretamente algumas construções de linguagem.No entanto, o compilador Java pode eliminar variáveis ​​​​não utilizadas.Por exemplo.se x foi atribuído, mas não usado em nenhum lugar, o compilador poderá descartar esse código.Da mesma forma, o compilador está incorporando todas as constantes estáticas.

Sim, ele é realmente removido da pilha, tornando o slot anteriormente ocupado por 'x' reutilizável por outra variável local.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top