Являются ли подтексты в Java отдельными строками в стеке?

StackOverflow https://stackoverflow.com/questions/3061194

Вопрос

В 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 (что является Язык структурированного программирования) пока они не являются частью составленного байтекода (что является неструктурированный язык).

Спецификация метода в файле класса указывает, сколько локальных переменных метод использует в общей сложности, выше фактического списка инструкций. Но где блоки один раз, где в коде Java не могут быть выведены из базового кода.

Прежде всего, в байт-коде переменные хранятся в слотах переменных и variable slots, а не в стеке.Слот может быть повторно использован другой переменной, но не гарантируется, что значение будет удалено из слота переменной.

Например, следующий класс

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

компилируется в этот байт-код:

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

Обратите внимание, что переменная x, созданная в строке 7, сохраняется в слоте переменной 2, который все еще доступен в байт-коде, соответствующем строке 10.

Нет никаких спецификаций о том, как язык Java должен быть скомпилирован в байт-код, за исключением нескольких примеров правильной компиляции некоторых языковых конструкций.Однако компилятору Java разрешено удалять неиспользуемые переменные.Например.если x был назначен, но нигде не использовался, компилятору разрешается удалить этот код.Аналогично, компилятор встраивает все статические константы.

Да, это действительно удаляется из стека, делая слот, ранее занятый «X», многоразовый с помощью некоторой другой локальной переменной.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top