_ (sublinhado) é uma palavra-chave reservada

92

Acabei de substituir sa seguinte expressão lambda por _:

s -> Integer.parseInt(s)

O compilador Eclipse diz:

'_' não deve ser usado como um identificador, uma vez que é uma palavra-chave reservada do nível de origem 1.8 em diante.

Eu não encontrei nenhuma explicação em JLS §3.9 Estrutura Lexical / Palavras-chave.

Aubin
fonte

Respostas:

83

O lugar para procurar é JLS §15.27.1. Parâmetros Lambda

É um erro em tempo de compilação se um parâmetro lambda tiver o nome _ (ou seja, um único caractere de sublinhado).

O uso do nome da variável _ em qualquer contexto é desencorajado. Versões futuras da linguagem de programação Java podem reservar esse nome como uma palavra-chave e / ou dar a ele uma semântica especial.

Portanto, a mensagem do Eclipse é enganosa, especialmente porque a mesma mensagem é usada para ambos os casos, quando um erro é gerado para um parâmetro lambda ou quando um aviso é gerado para qualquer outro _identificador.

Holger
fonte
21
Observe que, a partir do Java 9, _não será permitido qualquer nome de identificador legal e não apenas um nome de parâmetro lambda. Na verdade, isso foi corrigido na versão 43: bugs.openjdk.java.net/browse/JDK-8061549
Jean-François Savard
3
@lscoughlin: “Versões futuras da linguagem de programação Java podem reservar este nome como uma palavra-chave e / ou dar a ele uma semântica especial” declaração suficiente? Bem, substitua “pode reservar” por “usará” e você entenderá. Talvez esta referência de e-mail ajude…
Holger
5
O que é isso? Java quebrando compatibilidade com versões anteriores?
Arturo Torres Sánchez
8
@Arturo Torres Sánchez: isso não é novidade. Houve momentos em que enume assertforam identificadores legais ...
Holger
11
@Holger, na verdade, existem toneladas de linguagens que usam o sublinhado como espaço reservado para o nome (Scala, Clojure, F #, SML, Erlang, apenas para citar alguns). É um padrão estabelecido que remonta aos anos 90 ou 80, acredito, então desobedecê-lo é estranho.
om-nom-nom
23

É a Fase 2 do JEP 302 , que vai adicionar o sublinhado como um caractere especial para denotar parâmetros não utilizados em expressões lambda.

Tratamento de sublinhados

Em muitas linguagens, é comum usar um sublinhado ( _) para denotar um parâmetro lambda sem nome (e da mesma forma para parâmetros de método e exceção):

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

Isso permite uma verificação estática mais forte de argumentos não usados ​​e também permite que vários argumentos sejam marcados como não usados. No entanto, como o sublinhado era um identificador válido no Java 8, a compatibilidade exigia que adotássemos um caminho mais indireto para chegar onde o sublinhado poderia servir a essa função em Java. A fase 1 estava proibindo o sublinhado como um nome de parâmetro formal lambda no Java 8 (isso não tinha nenhuma consequência de compatibilidade, já que lambdas não existiam anteriormente) e um aviso foi emitido para usar o sublinhado como um identificador em outros lugares. A fase 2 veio no Java 9, quando esse aviso se tornou um erro. Agora estamos livres para concluir a reabilitação planejada de sublinhado para indicar um lambda, método ou parâmetro formal de captura não utilizado.

Alexandre de Champeaux
fonte
1
Esse uso é discutido por Brian Goetz em sua palestra Devoxx de 2017-11 sobre o Projeto Amber .
Basil Bourque
OK, mas qual é a alternativa para denotar parâmetros não utilizados no J8? Isso não é possível?
Manuel
1
Atualmente usamos $para este propósito.
aventurin
Estou no Java 14 agora e ainda não consigo usar um sublinhado como um parâmetro lambda sem nome. Seja o que for que o JCP se propôs alcançar, parece que alcançou o oposto.
Frans
@Frans Observe que o JEP está (a partir de hoje) apenas no estágio de candidato. Ainda não foi concluído. Para mais detalhes sobre o processo JEP, consulte JEP 1
Alexandre de Champeaux