Массивы как локальные переменные - не следуйте правилу определенного присваивания в лямбде - PullRequest
0 голосов
/ 12 февраля 2019

Видел следующие потоки:

Сообщение компилятора Java8 Stream - локальная переменная должна быть окончательной или фактически окончательной

Назначение переменной в лямбда-выражении

Согласно JavaDoc

Любая локальная переменная, формальный параметр или параметр исключения, используемый, но не объявленный в лямбда-выражении, должен быть объявлен как final илифактически завершается (§4.12.4), или возникает ошибка времени компиляции при попытке использования.

Любая локальная переменная, используемая, но не объявленная в лямбда-теле, должна быть точно назначена (§16 (Определенное назначение)) до появления лямбда-тела или ошибки времени компиляции.

Аналогичные правила использования переменных применяются в теле внутреннего класса (§8.1.3).Ограничение на эффективные конечные переменные запрещает доступ к динамически изменяющимся локальным переменным, захват которых может привести к проблемам с параллелизмом.По сравнению с последним ограничением, это уменьшает нагрузку на программистов.

Является arrays исключением из правила 1 ?

Пример программы, которая проверяет Javadoc:

List<Integer> li = Arrays.asList(1,2,3,45,678); 
final int v = 2;
li.stream().filter(e-> e!=v).map(e->e).forEach(System.out::println);
v= 5;   

Ошибка компиляции в строке v = 5; , очевидно,

Пример фрагмента, который нарушает окончательное правило назначения:

List<Integer> li = Arrays.asList(1,2,3,45,678); 
final int[] v = {2};
li.stream().filter(e-> e!=v[0]).map(e->e).forEach(System.out::println);
v[0]= 5;

Вывод:

3

45

678

Выше фрагмент не дает ошибки компиляции, я что-то упустил ??

1 Ответ

0 голосов
/ 12 февраля 2019

В первом случае v является переменной типа int, здесь значение v равно 2, и это final переменная.когда вы пытаетесь присвоить 5, это дает ошибку, потому что вы не можете изменить final значение переменной (работает как положено).

Приходит ко второму случаю, v не в переменной типа intЭто array.В Java массивы являются объектами, поэтому здесь v является ссылкой.Обычно ссылка относится к объекту и содержит адрес объекта.Когда вы пытаетесь сделать v[0] = 5 здесь, вы меняете значение внутри объекта, но не значение ссылки.Если вы попытаетесь сделать v = new int[1] или v={5}, вы получите ошибку компиляции

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...