2016-10-15 9 views
0

Когда я использую лямбда-выражения или анонимных внутренних классов, с переменными из внешнего класса, я часто получаю ошибку во время компиляции:

Ламба выражений:Являются ли эффективные окончательные переменные интерпретируемыми как final компилятором в Java 8?

local variables referenced from a lambda expression must be final or effectively final 

Внутренние классы:

local variables referenced from an inner class must be final or effectively final 


Это означает, что компилятор в Java 8 может определить, является ли переменная неявно окончательной или нет.
Что касается вопроса this, использование конечных переменных вместо нефиналов иногда дает огромное потенциальное влияние на производительность.
Мой вопрос:
Компилятор в java 8 эффективно интерпретирует конечные переменные как конечные переменные, а позже, во время выполнения, использует его как final?
В результате, он делает ту же оптимализацию, что и для конечных переменных?

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

Буду благодарен за любые ответы.

ответ

1

Does compiler in java 8 interpret effectively final variables as final variables and later, in runtime use it as final?

Ответ будет да в обоих случаях.

Причина последнего заключается в том, что формат файла класса не дает возможности указать, объявлена ​​ли локальная переменная как final. Поэтому, если JIT-компилятор будет оптимизирован на основе окончательности, окончательность должна быть выведена из того, что фактически делают байт-коды метода; то есть эффективную завершенность.

0

«Что касается этого вопроса, то использование конечных переменных вместо нефиналов иногда дает огромное потенциальное влияние на производительность».

Если я правильно понял вопрос, с которым вы связались, это действительно не имеет никакого отношения к «эффективно финальному». Положительные последствия, которые вы имеете в виду, относятся к экземплярам переменные (которые не являются частными); объявление их final может быть полезно, потому что это означает, что компилятор может быть уверен, что ни один метод в подклассе не может изменить переменную.

«Эффективно окончательный» - это понятие, которое применяется только к локальным переменным, объявленным внутри метода (включая параметры). Нет никакой возможности, чтобы локальная переменная в методе могла быть изменена в подклассе.

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