_ (subrayado) es una palabra clave reservada

92

Acabo de reemplazar sla siguiente expresión lambda por _:

s -> Integer.parseInt(s)

El compilador de Eclipse dice:

'_' no debe usarse como identificador, ya que es una palabra clave reservada desde el nivel de fuente 1.8 en adelante.

No he encontrado ninguna explicación en JLS §3.9 Estructura léxica / Palabras clave.

Aubin
fuente

Respuestas:

83

El lugar para buscar es JLS §15.27.1. Parámetros Lambda

Es un error en tiempo de compilación si un parámetro lambda tiene el nombre _ (es decir, un solo carácter de subrayado).

Se desaconseja el uso del nombre de variable _ en cualquier contexto. Las versiones futuras del lenguaje de programación Java pueden reservar este nombre como palabra clave y / o darle una semántica especial.

Entonces, el mensaje de Eclipse es engañoso, especialmente porque el mismo mensaje se usa para ambos casos, cuando se genera un error para un parámetro lambda o cuando se genera una advertencia para cualquier otro _identificador.

Holger
fuente
21
Tenga en cuenta que a partir de Java 9, _no se permitirá como nombre de identificador legal y no solo como nombre de parámetro lambda. En realidad, esto se solucionó en la compilación 43: bugs.openjdk.java.net/browse/JDK-8061549
Jean-François Savard
3
@lscoughlin: ¿No es suficiente la declaración “Las versiones futuras del lenguaje de programación Java pueden reservar este nombre como palabra clave y / o darle una semántica especial”? Bueno, reemplace "puede reservar" por "utilizará", y obtendrá la imagen. Quizás esta referencia por correo ayude ...
Holger
5
¿Que es esto? ¿Java rompiendo la compatibilidad con versiones anteriores?
Arturo Torres Sánchez
8
@Arturo Torres Sánchez: eso no es nada nuevo. Hubo momentos en que enumy asserteran identificadores legales…
Holger
11
@Holger en realidad hay toneladas de lenguajes que usan subrayado como marcador de posición de nombre (Scala, Clojure, F #, SML, Erlang, solo por nombrar algunos). Es un patrón establecido que se remonta a los 90 u 80, creo, así que desobedecerlo es extraño.
om-nom-nom
23

Es la Fase 2 de JEP 302 , que va a agregar un subrayado como un carácter especial para denotar los parámetros no utilizados en las expresiones lambda.

Tratamiento de guiones bajos

En muchos idiomas, es común usar un guión bajo ( _) para denotar un parámetro lambda sin nombre (y de manera similar para los parámetros de método y excepción):

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

Esto permite una comprobación estática más sólida de los argumentos no utilizados y también permite marcar varios argumentos como no utilizados. Sin embargo, debido a que el subrayado era un identificador válido a partir de Java 8, la compatibilidad requería que tomáramos una ruta más indirecta para llegar a donde el subrayado podría cumplir esta función en Java. La fase 1 prohibía el subrayado como un nombre de parámetro formal de lambda en Java 8 (esto no tenía consecuencias de compatibilidad, ya que las lambdas no existían anteriormente) y se emitió una advertencia para usar el subrayado como identificador en otros lugares. La fase 2 llegó en Java 9, cuando esta advertencia se convirtió en un error. Ahora tenemos la libertad de completar la rehabilitación planificada del subrayado para indicar un parámetro formal de captura, método o lambda no utilizado.

Alexandre de Champeaux
fuente
1
Brian Goetz analiza este uso en su charla Devoxx de 2017-11 sobre el Proyecto Amber .
Basil Bourque
Bien, pero ¿cuál es la alternativa para denotar parámetros no utilizados en J8? ¿No es eso posible en absoluto?
Manuel
1
Actualmente usamos $para este propósito.
aventurin
Estoy en Java 14 ahora y todavía no puedo usar un guión bajo como parámetro lambda sin nombre. Independientemente de lo que se propuso lograr el PCJ, parece que han logrado lo contrario.
Frans
@Frans Tenga en cuenta que el JEP está (a partir de hoy) solo en la etapa de candidato. Aún no se ha completado. Para obtener más detalles sobre el proceso de JEP, consulte JEP 1
Alexandre de Champeaux