_ (підкреслення) - зарезервоване ключове слово


94

Я щойно замінив sнаступний лямбда-вираз на _:

s -> Integer.parseInt(s)

Компілятор Eclipse каже:

'_' не слід використовувати як ідентифікатор, оскільки це зарезервоване ключове слово з рівня джерела 1.8.

Я не знайшов жодного пояснення в § 3.9 Лексичної структури / ключових слів JLS .

Відповіді:


86

Місце для пошуку - JLS §15.27.1. Параметри лямбди

Помилка під час компіляції, якщо лямбда-параметр має ім'я _ (тобто один символ підкреслення).

Не рекомендується використовувати ім'я змінної _ у будь-якому контексті. Майбутні версії мови програмування Java можуть зарезервувати це ім'я як ключове слово та / або надати йому особливу семантику.

Отже, повідомлення Eclipse вводить в оману, тим більше, що одне і те ж повідомлення використовується в обох випадках, коли генерується помилка для лямбда-параметра або коли генерується попередження для будь-якого іншого _ідентифікатора.


24
Зверніть увагу, що з Java 9 _заборонено використовувати будь-які юридичні імена ідентифікаторів, а не лише як ім'я лямбда-параметра. Це насправді було виправлено у збірці 43: bugs.openjdk.java.net/browse/JDK-8061549
Жан-Франсуа Савард

3
@lscoughlin: Чи недостатньо твердження «Майбутні версії мови програмування Java можуть зарезервувати це ім’я як ключове слово та / або надати йому особливу семантику»? Ну, замініть "може зарезервувати" на "буде використовувати", і ви отримаєте картинку. Можливо, це посилання на пошту допомагає ...
Холгер,

5
Що це? Java порушує зворотну сумісність?
Артуро Торрес Санчес,

8
@Arturo Torres Sánchez: це нічого нового. Були часи, коли enumі assertбули юридичні ідентифікатори ...
Холгер

11
@Holger насправді існує маса мов, які використовують підкреслення як заповнювач імен (Scala, Clojure, F #, SML, Erlang, щоб назвати лише декілька). Це, як я вважаю, усталена закономірність, яка сягає 90-х чи 80-х років, тому непокора цьому є дивним.
om-nom-nom

25

Саме фаза 2 JEP 302 збирається додати підкреслення як спеціальний символ для позначення невикористаних параметрів у лямбда-виразах.

Обробка підкреслень

У багатьох мовах часто використовується символ підкреслення ( _) для позначення неназваного лямбда-параметра (і аналогічно для параметрів методу та винятку):

BiFunction<Integer, String, String> biss = (i, _) -> String.valueOf(i);

Це дозволяє посилити статичну перевірку невикористаних аргументів, а також дозволяє позначити декілька аргументів як невикористані. Однак, оскільки підкреслення було дійсним ідентифікатором на Java 8, сумісність вимагала від нас більш непрямого шляху до місця, де підкреслення могло б виконувати цю роль на Java. Фаза 1 забороняла підкреслення як ім'я формального параметра лямбда в Java 8 (це не мало наслідків для сумісності, оскільки лямбди раніше не існували), і було видано попередження про використання підкреслення як ідентифікатора в інших місцях. Етап 2 відбувся в Java 9, коли це попередження стало помилкою. Тепер ми можемо завершити заплановану реабілітацію підкреслення, щоб вказати невикористаний лямбда, метод або формальний параметр.


2
Це використання обговорюється Брайаном Гетцом у його виступі Devoxx 2017-11 про проект Amber .
Василь Бурк,

Добре, але яка альтернатива позначає невикористані параметри в J8? Це взагалі не можливо?
Мануель

1
В даний час ми використовуємо $для цієї мети.
Aventurin

1
Зараз я на Java 14, і я все ще не можу використовувати підкреслення як неназваний лямбда-параметр. Що б не намагався досягти СКП, схоже, вони досягли протилежного.
Франс

1
@Frans Зауважте, що JEP (на сьогоднішній день) знаходиться лише на стадії кандидата. Він ще не завершений. Детальніше про процес JEP див. У JEP 1
Олександр де Шампо

5

Зміни мови Java для Java SE 9 https://docs.oracle.com/javase/9/language/toc.htm#JSLAN-GUID-16A5183A-DC0D-4A96-B9D8-AAC9671222DD

З Java 9 символ _ більше не можна використовувати в якості ідентифікатора, не лише в контексті лямбда

Символ підкреслення не є офіційною назвою.

Якщо ви використовуєте символ підкреслення ("_") для ідентифікатора, ваш вихідний код більше не можна компілювати.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.