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

Как обозначение переменной как final позволяет внутренним классам обращаться к ним?

внутренний класс, определенный внутри метода, не может получить доступ к локальным переменным метода, если только эти локальные переменные не отмечены final. Я рассматривал другие сообщения в раннем переполнении стека и ранжирования java-кода, но ни один из них, похоже, точно отвечают на вопрос о том, как окончательные обозначения переменных позволяют внутреннему классу обращаться к локальным переменным в методе.

class MyOuter {
    private String x = "Outer";

    void fly(final int speed) {
        final int e = 1;
        class FlyingEquation {

            public void seeOuter()
            {
                System.out.println("Outer x is " + x);
            }
            public void display()
            {
                System.out.println(e);// line 1
                System.out.println(speed);// line 2
            }
        }
        FlyingEquation f=new FlyingEquation();
        f.seeOuter();
        f.display();
    }       
    public static void main(String args[])
    {
        MyOuter mo=new MyOuter();
        mo.fly(5);
    }
}

Пояснения: Я нашел следующее:

локальные переменные хранятся в стеке, и как только вызов метода заканчивается, стек выставляется, а локальные переменные недоступны, тогда как конечные локальные переменные strong > хранятся в разделе данных памяти, что позволяет JVM получить к ним доступ даже после завершения вызова метода. Где находится data section of memory? Я считаю, что все локальные переменные final или not хранятся в стеке. Когда этот метод удаляется из стека, конечная переменная будет удалена вместе с ним. Является ли это тем, что значение в конечной переменной хранится с объектом в куче?

Он не поддерживает нефинализированные поля, поскольку они могут быть изменены либо методом, либо классом, и это не поддерживается, поскольку на самом деле существует два разных поля/переменных.

4b9b3361

Ответ 1

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

Ответ 2

Маркировка локальной переменной как final сообщает компилятору, что ее значение не будет изменяться после его назначения. Это делает безопасным создание компилятором синтетического поля внутри внутреннего класса и копирование значения локальной переменной в это синтетическое поле при создании внутреннего экземпляра класса. Все чтения локальной переменной изнутри внутреннего кода класса фактически компилируются при чтении синтетического поля.

Этот трюк не будет работать для не конечных переменных, поскольку они могут измениться после создания внутреннего класса, и синтетическое поле перестанет синхронизироваться с исходной переменной.

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

Ответ 3

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

Ответ 4

История заключается в том, что создателям java не хватило времени, чтобы полностью поддержать closure.

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

Таким образом, они создают внутренний класс, чтобы иметь версию закрытия для человека, которая имитирует стиль ML.

Ответ 5

Метод Локальные внутренние классы не могут использовать локальную переменную внешнего метода, пока локальная переменная не будет объявлена ​​окончательной. Основная причина, по которой нам нужно объявить локальную переменную как final, заключается в том, что локальная переменная живет в стеке, пока метод не находится в стеке, но может быть случай, когда объект внутреннего класса все еще живет в куче.

checkout this article: http://www.geeksforgeeks.org/inner-class-java/

Ответ 6

Теперь подумайте об этом. Локальные переменные метода живут в стеке и существуют только для времени жизни метода. Мы уже знаем, что область локальной переменной ограничена методом, в котором объявлена ​​переменная. Когда метод заканчивается, кадр стека сбрасывается и переменная является историей. Но даже после завершения метода внутренний объект класса, созданный внутри него, может быть еще жив в куче, если, например, ссылка на него была передана в какой-то другой код, а затем сохранена в переменной экземпляра, Поскольку локальные переменные не гарантированно остаются живыми до тех пор, пока объект локального внутреннего класса метода не используется, внутренний объект класса не может их использовать. Если локальные переменные не отмечены final.

Сохраняются ли последние локальные переменные в куче вместо стека?

Объяснение: Теперь, после некоторых исследований в SO, я узнал, что вся локальная переменная (final или not) хранится в стек и идет вне области, когда выполнение метода завершено.

О финале переменная JVM воспринимает их как константу, поскольку они не будут меняться после начато. И когда внутренний класс пытается получить к ним доступ, компилятор создает копию этой переменной (не той переменной it self) в кучуи создайте синтетическое поле внутри внутреннего класса, поэтому даже когда выполнение метода завершено, потому что внутренний класс имеет свою собственную копию. Синтетическое поле, которые на самом деле не существуют в исходном коде, но компилятор создает эти поля в некоторых чтобы сделать эти поля доступными. Простое слово скрыто поле.

Таким образом, конечная переменная также сохраняется в стеке, но копия этой переменной, которую внутренний класс хранит в куче.