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

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

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

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

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

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

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


person Joel    schedule 22.12.2009    source источник


Ответы (1)


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

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

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

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

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

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

person Thilo    schedule 22.12.2009
comment
Могу ли я предположить, что в результате этого не возникнет проблем с производительностью? - person Joel; 22.12.2009
comment
Мое личное раздражение в этой области заключается в том, что ссылки на внешний экземпляр (используемый для доступа к полям, а не к копируемым переменным) могут быть проблемой, если они не нужны: stackoverflow.com/questions/ 758570 / - person Thilo; 22.12.2009
comment
по сравнению со ссылкой на него как на переменную-член. Если он скопирован, то я предполагаю, что это не повлияет на производительность. - person Joel; 22.12.2009
comment
да, это то же самое (только меньше набора текста), поскольку вы за кулисами фактически ссылаетесь на синтетическую переменную-член, которую компилятор создал для вас во внутреннем классе, чтобы хранить копию последней переменной. - person Thilo; 22.12.2009
comment
вы получите мой голос, если добавите ссылку или работу, которая заставила вас поверить в это. - person David Waters; 22.12.2009