Предоставляет ли Java 10 ключевое слово val? Если нет, то почему?


person sdgfsdh    schedule 22.03.2018    source источник
comment
Не уверен, что вопрос да/нет был бы здесь хорошим вопросом. Но я не понимаю, почему он должен включать и var, и val для одной и той же функции.   -  person AxelH    schedule 22.03.2018
comment
Вероятно, нет: блог. codefx.org/java/java-10-var-type-inference/ Итак, это будет final var   -  person Thilo    schedule 22.03.2018
comment
@AxelH val и var имеют разные значения, поэтому они не являются одной и той же функцией.   -  person sdgfsdh    schedule 22.03.2018
comment
Оба делают вывод типа, один является окончательным, другой - нет. Это я так же называю. String и final String для вас разные типы?   -  person AxelH    schedule 22.03.2018
comment
В случае String тогда var будет эквивалентно String, а val будет эквивалентно final String. Они связаны, но не одно и то же.   -  person sdgfsdh    schedule 22.03.2018
comment
Вы <б> <я> попробуйте?   -  person Naman    schedule 22.03.2018
comment
Я думаю, что этот вопрос можно спасти, превратив его в вопрос «почему» вместо «да/нет» (принятый ответ остается в силе).   -  person Pixel Elephant    schedule 22.03.2018
comment
@PixelElephant честная точка зрения; вопрос обновлен   -  person sdgfsdh    schedule 23.03.2018
comment
@sdgfsdh Почему бы вам не попробовать код Kotlin в своем java-проекте. Kotlin предоставляет ключевое слово val. Вы можете использовать Kotlin в коде Java и наоборот. Вы можете найти пример используемого кода здесь, в котором используется ключевое слово val.   -  person RRadley    schedule 27.12.2018


Ответы (3)


В Java 10 нет val, как указано в JEP 286: определение типа локальной переменной:

Выбор синтаксиса

Мнения о синтаксисе расходились. Здесь есть две основные степени свободы: какие ключевые слова использовать (var, auto и т. д.) и нужна ли отдельная новая форма для неизменяемых локальных переменных (val, let). Мы рассмотрели следующие синтаксические варианты:

  • var x = только expr (как C#)
  • var плюс val для неизменяемых локальных переменных (например, Scala, Kotlin)
  • var, а также let для неизменяемых локальных переменных (например, Swift)
  • auto x = expr (как C++)
  • const x = expr (уже зарезервированное слово)
  • final x = expr (уже зарезервированное слово)
  • пусть х = выражение
  • def x = expr (как Groovy)
  • x := expr (как в Go)

После сбора значительного количества входных данных var явно предпочтительнее подходов Groovy, C++ или Go. Мнения по поводу второй синтаксической формы для неизменяемых локалов (val, let) разошлись во мнениях. это было бы компромиссом между дополнительной церемонией и дополнительным отражением дизайнерского замысла. В итоге мы решили поддерживать только var. Некоторые подробности обоснования можно найти здесь.

И вот основные рассуждения:

Я знаю, что это та часть, которая действительно волнует людей :) После подробного рассмотрения плюсов и минусов, кажется, очевидный победитель - var-only. Причины этого включают:

  • Хотя это был не самый популярный выбор в опросе, очевидно, что большинство людей согласились с ним. Многие ненавидели вар/вал; другие ненавидели var/let. Почти никто не ненавидел вар-только.

  • Опыт работы с C#, в котором есть только var, показал, что это разумное решение для Java-подобных языков. В C# нет большого спроса на "val".

  • Желание сократить церемонию непреложности, безусловно, правильное, но в данном случае это давка не на тот конец рычага. Где нам нужна помощь для неизменности, так это в полях, а не в локальных. Но var/val не применяется к полям и почти наверняка никогда не будет.

  • Если бы дополнительные накладные расходы на получение контроля над изменчивостью по сравнению с выводом типов были бы нулевыми, то мог бы быть более сильный аргумент, но было ясно, что многие люди считают два разных ведущих ключевых слова отвлекающими факторами, которые мешают их глазам быстро остановиться на важных вещах. . Если имена переменных более важны, чем типы, они также более важны, чем модификаторы изменчивости.

(Источник)

person Eran    schedule 22.03.2018
comment
[..] Некоторые подробности обоснования можно найти здесь - person AxelH; 22.03.2018
comment
Неизменяемость важна, но на самом деле локальные переменные — это наименее важная область, где нам нужна помощь в обеспечении неизменяемости. Локальные переменные невосприимчивы к гонкам данных; большинство местных жителей в любом случае являются окончательными. Где нам нужна дополнительная помощь в поощрении неизменяемости, так это в *полях*, но применять вывод типов здесь было бы глупо. - person AxelH; 22.03.2018
comment
Интересно, а можно ли улучшить final для этого подхода? А именно, для поддержки такого использования: final varName = new Object(). Разве не логично, что если вы ставите final внутри методов, то вы имеете в виду final var? Просто, может быть, глупая фантазия. - person ekar; 09.04.2020
comment
@Eran Я думаю, что определенно упустили из виду, что в большинстве программ НАМНОГО меньше случаев, когда нам нужны переменные, по сравнению с константами. Было бы намного полезнее поддерживать val вместо var IMO, и люди также перестали бы объявлять переменные там, где было бы достаточно констант... - person plalx; 31.12.2020
comment
Например, поскольку JavaScript добавил const, почти никто не использует let без необходимости. Кроме того, аргумент о том, что 2 ключевых слова будут слишком отвлекающими, абсурден. Они могли прочитать все эти явные объявления типов и вдруг слишком отвлеклись на var/val или var/let, чтобы понять код? Лучше поддерживать изменчивость по сравнению с неизменностью так же абсурдно, как разрешить ссылкам быть null по умолчанию... - person plalx; 31.12.2020

Потому что в Java для этого есть final var. Если бы у нас тоже было val, то были бы две вещи, которые означали бы одно и то же. Это не хорошо. Должен быть только один способ выразить конкретную вещь.

person ZhekaKozlov    schedule 26.05.2018
comment
var также, кажется, не выражает ничего, что раньше было невозможно. И var, и val просто делают вещи короче. - person Michal M; 15.11.2018
comment
var выражает то, что раньше было невозможно: реальный тип анонимного класса. Например, теперь можно выполнить var foo = new Object() { int i = 1; }; и получить доступ к foo.i без отражения. Конечно, это полезно только внутри тела метода, поскольку вы можете вернуть только супертип. - person Micheal Hill; 25.02.2020
comment
@MichealHill На самом деле это было возможно раньше. Например. вы можете написать t(new Object() { int i = 1; }).i в Java 8, где t определяется как public static <T> T t(T t) { return t; }. - person ZhekaKozlov; 25.02.2020
comment
Это очень самоуверенный ответ без четкой основы. Цикл можно выразить множеством способов: for(;;), for (x : y), .forEach, do..while... - person Lucas Ross; 18.06.2020

Если вы хотите использовать "val", то есть "final var", вы всегда можете использовать значение Lombok.

person Alberthoven    schedule 26.11.2019
comment
Не всегда... Ломбок — это хак: github.com/projectlombok/lombok/issues/2131 github.com/projectlombok/lombok/issues/2652 - person WindyFields; 07.07.2021