_ (trait de soulignement) est un mot-clé réservé

92

Je viens de remplacer sdans l'expression lambda suivante par _:

s -> Integer.parseInt(s)

Le compilateur Eclipse dit:

«_» ne doit pas être utilisé comme identifiant, car il s'agit d'un mot clé réservé à partir du niveau source 1.8.

Je n'ai trouvé aucune explication dans le JLS §3.9 Structure lexicale / Mots-clés.

Aubin
la source

Réponses:

83

L'endroit à regarder est JLS §15.27.1. Paramètres Lambda

Il s'agit d'une erreur de compilation si un paramètre lambda porte le nom _ (c'est-à-dire un seul caractère de soulignement).

L'utilisation du nom de variable _ dans n'importe quel contexte est déconseillée. Les versions futures du langage de programmation Java pourront réserver ce nom comme mot-clé et / ou lui donner une sémantique spéciale.

Le message Eclipse est donc trompeur, d'autant plus que le même message est utilisé dans les deux cas, lorsqu'une erreur est générée pour un paramètre lambda ou lorsqu'un avertissement est généré pour tout autre _identifiant.

Holger
la source
21
Notez qu'à partir de Java 9, _il sera interdit en tant que nom d'identifiant légal et pas seulement en tant que nom de paramètre lambda. Ce problème a
Jean-François Savard
3
@lscoughlin: La déclaration «Les futures versions du langage de programmation Java pourraient réserver ce nom comme mot-clé et / ou lui donner une sémantique spéciale» n'est-elle pas suffisante? Eh bien, remplacez «peut réserver» par «utilisera», et vous obtiendrez l'image. Peut - être que cette référence de messagerie aide…
Holger
5
Qu'est-ce que c'est? Java rompt la compatibilité descendante?
Arturo Torres Sánchez
8
@Arturo Torres Sánchez: ce n'est pas nouveau. Il y avait des moments où enumet assertétaient des identifiants légaux…
Holger
11
@Holger en fait, il existe des tonnes de langages qui utilisent le trait de soulignement comme espace réservé pour le nom (Scala, Clojure, F #, SML, Erlang, pour n'en nommer que quelques-uns). C'est un schéma établi qui remonte aux années 90 ou 80, je crois, alors désobéir est étrange.
om-nom-nom
23

C'est la phase 2 de JEP 302 , qui va ajouter un trait de soulignement comme caractère spécial pour désigner les paramètres inutilisés dans les expressions lambda.

Traitement des traits de soulignement

Dans de nombreux langages, il est courant d'utiliser un trait de soulignement ( _) pour désigner un paramètre lambda sans nom (et de même pour les paramètres de méthode et d'exception):

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

Cela permet une vérification statique plus forte des arguments inutilisés et permet également de marquer plusieurs arguments comme inutilisés. Cependant, comme le soulignement était un identifiant valide à partir de Java 8, la compatibilité nous obligeait à emprunter un chemin plus indirect pour arriver à l'endroit où le soulignement pouvait jouer ce rôle dans Java. La phase 1 interdisait le trait de soulignement en tant que nom de paramètre formel lambda dans Java 8 (cela n'avait aucune conséquence sur la compatibilité, car les lambdas n'existaient pas auparavant) et un avertissement a été émis pour l'utilisation de soulignement comme identifiant à d'autres endroits. La phase 2 est arrivée dans Java 9, lorsque cet avertissement est devenu une erreur. Nous sommes maintenant libres de terminer la réhabilitation prévue du trait de soulignement pour indiquer un paramètre formel lambda, une méthode ou une capture non utilisé.

Alexandre de Champeaux
la source
1
Cet usage est discuté par Brian Goetz dans son discours Devoxx de 2017-11 sur le projet Amber .
Basil Bourque
OK, mais quelle est l'alternative pour désigner les paramètres inutilisés dans J8? N'est-ce pas possible du tout?
Manuel
1
Nous utilisons actuellement $à cette fin.
aventurin
Je suis sur Java 14 maintenant, et je ne peux toujours pas utiliser un trait de soulignement comme paramètre lambda sans nom. Quels que soient les objectifs du JCP, il semble qu'ils aient réussi le contraire.
Frans
@Frans Notez que le JEP n'est (à ce jour) qu'au stade candidat. Il n'est pas encore terminé. Pour plus de détails sur le processus JEP, voir JEP 1
Alexandre de Champeaux