Подтвердить что ты не робот

Где хранятся конечные локальные переменные Java?

Возьмем следующий пример:

public void init() {
    final Environment env = new Environment();
    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
             env.close();
        }
     });
}

Во-первых, где хранится env? Это:

  • скопированный компилятором в скрытую переменную-член внутреннего класса, который ссылается на нее
  • скопирован в кучу
  • осталось в стеке и как-то ссылается там
  • что-то еще

Мое предположение - это первый вариант.

Во-вторых, делайте какие-либо проблемы с производительностью, возникающие в результате этого (вместо того, чтобы просто создавать env как переменную-член класса и ссылаться на нее как таковой), особенно если вы создаете большое количество таких внутренних конструкций класса, которые ссылаются на final локальные переменные.

4b9b3361

Ответ 1

Да, они скопированы, поэтому вам нужно объявить переменную как final. Таким образом, они гарантированно не изменятся после того, как была сделана копия.

Это разные поля для экземпляра, которые доступны, даже если они не являются окончательными. В этом случае внутренний класс получает ссылку на внешний экземпляр, который он использует для этой цели.

private Environment env;  // a field does not have to be final

public void init() {
    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
             env.close();
        }
     });
}

Во-вторых, какие-либо проблемы с производительностью, возникающие в результате этого?

По сравнению с чем? Вам нужно иметь поле или переменную для вашего внутреннего класса, чтобы работать, а копия - очень эффективный способ. Это всего лишь "мелкая" копия: просто ссылка на (в вашем примере) Скопирована среда, а не сама среда.