powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / По какой причине разрабы запретили делать так
21 сообщений из 21, страница 1 из 1
По какой причине разрабы запретили делать так
    #38945239
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По какой причине запрещено делать так:

Код: java
1.
2.
String myvar;
callSomeMethod((someValue)->{myvar=someValue})



Все равно ведь нужное поведение делается вот так, но это переутяжеляет синтаксис:
Код: java
1.
2.
String[] myvar={null};
callSomeMethod((someValue)->{myvar[0]=someValue})
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38945243
rema174
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
chabapok,

имхо, потому что выглядит как бред )

p.s. в какой конторе?
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38945292
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rema174,

Бгг. Не, ну если вопрос ставить так, то получается, что в oracle :)

Оно не компилируется по варианту 1. Теоретически, где-то в JLS должно быть написано прямо или косвенно.
Это скорей всего значит, что есть какие-то веские причины.
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38945301
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapokТеоретически, где-то в JLS должно быть написано прямо или косвенно. http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.3 Any local variable, formal method parameter or exception handler parameter used but not declared in an inner class must be declared final. Any local variable, used but not declared in an inner class must be definitely assigned before the body of the inner class.
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38945325
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да... В какомто из видео еще говорили, что в 1.6 жаве ставилось требование, чтобы такая переменная была финальная. Потом то ли в 7 то ли в 8 это требование смягчили - можно слово финал не писать, но менять переменную все равно нельзя.
Почему не смягчили до того, чтобы ее:
- можно было менять
- можно было менять внутри кода внутренего класса

видимо это связано с оптимизациями какими-то.
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38945331
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это связано с тем, что лямба может быть вызвана очень нескоро, а значит модифицируемая переменная будет создавать и проблемы и неопределённости.
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38945444
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://www.ibm.com/developerworks/library/j-ldn2/

Кстати, Goetz говорит, что то что вам насоветовали, тоже кагбе неправильно :)
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38947985
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл ник,


а какие потенциальные ошибки тут возможны, и как тогда правильно?
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38948013
scf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дело в том, что лямбду можно считать классом, который принимает в своем "конструкторе" все переменные, которые в этой лямбде упоминаются. Точно такой же механизм используется в non-static inner classes.

т.е. код
Код: java
1.
2.
String[] myvar={null};
callSomeMethod((someValue)->{myvar[0]=someValue})



превращается примерно в

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
String[] myvar={null};

callSomeMethod(new $Lambda(myvar) {
  private final String[] myvar;

  $Lambda(String[] myvar) {
     this.myvar = myvar;
  }

  void lambda(String someValue) {
    myvar[0]=someValue
  }
})



На самом деле все сложнее, но принцип именно такой. Это называется "захват параметров" или lambda parameter capture.
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38948014
scf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати - чтобы не извращаться с массивами, есть MutableObject из apache-lang3
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38949245
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
scfДело в том, что лямбду можно считать классом, который принимает в своем "конструкторе" все переменные, которые в этой лямбде упоминаются.

Все равно неясно, почему это плохо. Да, является классом. И что? Вон их в проекте сотни - и никто же не утверждает, что это плохо.
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38949284
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapokscfДело в том, что лямбду можно считать классом, который принимает в своем "конструкторе" все переменные, которые в этой лямбде упоминаются.

Все равно неясно, почему это плохо. Да, является классом. И что? Вон их в проекте сотни - и никто же не утверждает, что это плохо.

Если речь о том, почему нужно финальное, то суть в том, что в лябду уйдёт не сама переменная (это технически невозможно), а её копия.
Если менять переменную- то копия останется той же и всё пойдёт не так.
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38949322
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapokПо какой причине запрещено делать так:

Код: java
1.
2.
String myvar;
callSomeMethod((someValue)->{myvar=someValue})



Все равно ведь нужное поведение делается вот так, но это переутяжеляет синтаксис:
Код: java
1.
2.
String[] myvar={null};
callSomeMethod((someValue)->{myvar[0]=someValue})



Синтаксический сахар и приводит к полному недопониманию происходящего. Разницы с Java 1.4, кроме способа записи, почти никакой нет. Лямбды, хотя и не являются анонимными классами, но обладают всеми их свойствами. И требуют final переменных для захвата их из метода. А final необходим чтобы переменная вдруг не поменяла значение, вызывая неопределенность. Ведь лямбда и анонимный класс используют её копию. Вопроса про анонимный класс не возникает? Почему же тогда он возникает про лямбду?
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38949586
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вопрос про анонимный класс возникал такой же, просто в силу похожести вопросов я сократил и решил не повторять один и тот же вопрос дважды.

Получается, что если бы они заложили, что надо делать поддержку callSomeMethod((someValue)->{myvar=someValue}), то нельзя грабить переменную внутрь, значит анонимный класс должен был бы ссылаться на внутренюю область видимости метода, чтобы мочь поменять эту переменную. А такая фича ненужна.
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38949594
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapok,

Внешний метод и тело лямбды (анонимного класса) это 2 разных метода. Передать значение можно только через поле\аргумент.
Если вдруг переменная внешнего метода не финальная, то возникает вопрос, какое значение использовать в лямбде
1) Значение на момент объявления лямбды
2) Значение на момент вызова лямды

Во для того чтобы убрать неопределенность, добавили требование final.
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38949727
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz Внешний метод и тело лямбды (анонимного класса) это 2 разных метода. Передать значение можно только через поле\аргумент.
Если вдруг переменная внешнего метода не финальная, то возникает вопрос, какое значение использовать в лямбде
1) Значение на момент объявления лямбды
2) Значение на момент вызова лямды

Во для того чтобы убрать неопределенность, добавили требование final.

В момент вызова лямбды найти значение переменной в общем случае невозможно- она либо ГДЕ-ТО в стеке, либо вообще не существует (из метода уже вернулись). Так что единственный способ передать туда переменную- добавить неявное поле в объект-аноним и скопировать туда значение переменной. Именно на момент объявления лямбды.

Родился интересный код для собеседования, кстати :) Как-нибудь опишу.
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38949770
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczВо для того чтобы убрать неопределенность, добавили требование final.
Вопрос IMHO не столько в неопределенности, ее то можно решить по всякому. А теоретический.
Поле final это константа (т.е она неизменна) и поэтому может использоваться в любом контексте, в том числе и при создании кода метода. Переменная же это некоторая ячейка в памяти, которой может и вообще не быть в момент выполнения метода (в т.ч. и лямды), как и самого контекста, в котором она создавалась. Компилятор не может ссылаться на место в стеке, которое может быть освобождено или перезаписано, к моменту выполнения кода.
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38949802
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей АрсеньевBlazkowiczВо для того чтобы убрать неопределенность, добавили требование final.
Вопрос IMHO не столько в неопределенности, ее то можно решить по всякому. А теоретический.

Простите меня, но концентрация бреда зашкаливает...

Сергей Арсеньев Поле final это константа (т.е она неизменна)

Речь про локальную переменную, которая всегда есть часть стека. И не константа это, а именно что переменная.

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

Метод давно создан. Внутренний анонимный класс- это отдельный class-файл.

Сергей АрсеньевПеременная же это некоторая ячейка в памяти, которой может и вообще не быть в момент выполнения метода (в т.ч. и лямды)

Ещё раз- при создании объекта анонимного внутреннего класса все нужные локальные переменные копируются в (неявные) поля анонимного класса. Именно потому, что в момент его выполнения локальных переменных может и не быть.

И суть final - в том, чтобы гарантировать, что копия переменной в точности равна той самой локальной переменной.
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38949822
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey TominПростите меня, но концентрация бреда зашкаливает...
Сергей Арсеньев Поле final это константа (т.е она неизменна)
Речь про локальную переменную, которая всегда есть часть стека. И не константа это, а именно что переменная.
Это именно константа. Физически присутствует как неизменная переменная, но используется ее значение (ссылка на объект).
Исходя из ваших слов если используется сама ячейка в стеке, то как работает по вашему метод анонимного класса, лямды и пр., у которых доступа к этому стеку нет?

Сергей Арсеньеви поэтому может использоваться в любом контексте, в том числе и при создании кода метода.
Метод давно создан. Внутренний анонимный класс- это отдельный class-файл.
Давно по отношению к чему?

Сергей АрсеньевПеременная же это некоторая ячейка в памяти, которой может и вообще не быть в момент выполнения метода (в т.ч. и лямды)
Сергей АрсеньевЕщё раз- при создании объекта анонимного внутреннего класса все нужные локальные переменные копируются в (неявные) поля анонимного класса. Именно потому, что в момент его выполнения локальных переменных может и не быть.
Копируются не переменные, а значения. И вообще переменная отличается от константы возможностью изменения. С точки зрения терминологии. И более ничем.

Сергей АрсеньевИ суть final - в том, чтобы гарантировать, что копия переменной в точности равна той самой локальной переменной.
Нифига он не гарантирует ничего, кроме декларированной неизменности, что тождественно равно с точки зрения терминологии понятию константа.
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38949899
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей АрсеньевAlexey TominПростите меня, но концентрация бреда зашкаливает...
пропущено...

Речь про локальную переменную, которая всегда есть часть стека. И не константа это, а именно что переменная.
Это именно константа. Физически присутствует как неизменная переменная, но используется ее значение (ссылка на объект).
Исходя из ваших слов если используется сама ячейка в стеке, то как работает по вашему метод анонимного класса, лямды и пр., у которых доступа к этому стеку нет?

Я ж говорю- копия в поле анонимного класса. А как ещё?

В java есть просто переменные, есть final переменные (которые, если постараться, можно изменить) и есть константы (static final), которые реально подставляются компилятором в код, что может (для простых типов) привести к смешным результатам.
Так вот в данном случае это именно что финальная переменная, значение которой не известно компилятору (в отличии отнастоящей константы).

Сергей АрсеньевAlexey TominСергей Арсеньеви поэтому может использоваться в любом контексте, в том числе и при создании кода метода.
Метод давно создан. Внутренний анонимный класс- это отдельный class-файл.
Давно по отношению к чему?

Давно по отношению к моменту создания объекта.

Сергей АрсеньевИ вообще переменная отличается от константы возможностью изменения. С точки зрения терминологии. И более ничем.

Вы неправы :)

Сергей АрсеньевAlexey TominИ суть final - в том, чтобы гарантировать, что копия переменной в точности равна той самой локальной переменной.
Нифига он не гарантирует ничего, кроме декларированной неизменности, что тождественно равно с точки зрения терминологии понятию константа.

Нет :)
...
Рейтинг: 0 / 0
По какой причине разрабы запретили делать так
    #38949916
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Tomin,

Да ладно - вопрос терминологии. С точки зрения рефлексии и unsafe, чтобы изменить static final надо делать по другому.
Принципиально, наши позиции совпадают. Просто то, что я называю константа, Вы называете неизменной переменной.
И да - я разделяю понятия константа времени компиляции и константа времени выполнения.
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / По какой причине разрабы запретили делать так
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]