No se puede refactorizar métodos con subrayado como un parámetro en lambdas?
Tengo un montón de clases con un método (la mitad de ellos no utilizan su parámetro y por lo tanto el nombre de subrayado), y acabo de cambiar a Java 8. Ahora quiero reemplazarlos por lambdas.
Aquí está mi código:
- NoSuchMethodError con Android Lambdas
- Android Jack: Lambda que viene del archivo jar necesita sus interfaces en el classpath para ser compilado, las interfaces desconocidas son java.util.function.Consumer
- Aplicación de Android + Módulo de Java (Java 1.8)
- Android studio: las expresiones lambda no son compatibles en -source 1.7 (use -source 8 o superior para permitir expresiones lambda)
- Filtra una lista de objetos en Android usando gradle-retrolambda y Lightweight-Stream-API
interface I { void stuffHappened(Integer howManyStuff); } public class A { void go() { I i = new I() { public void stuffHappened(Integer _) { System.out.println("woah!!"); } }; } }
Y después:
interface I { void stuffHappened(Integer howManyStuff); } public class A { void go() { I i = _ -> System.out.println("woah!!"); } }
Como puede ver, al parecer ya no es válido, alegando el uso de "_" como el nombre del parámetro ya no es válido. Pero entonces, ¿por qué permitió este refactor en primer lugar? ¿Y por qué funciona con clases anónimas, pero no lambdas? ¿Es esto realmente una nueva regla? ¿O es algún tipo de discrepancia en IDEA?
Estoy usando Intellij-IDEA (la primera vez que lo uso), bueno en realidad, Android Studio (Beta) 0.8.1 (utilizando retrolambda para permitir lambdas en android), que creo que utiliza IDEA.
- Java.lang.NoClassDefFoundError $$ inlined $ forEach $ lambda $ 1 en Kotlin
- Uso de expresiones lambda con interfaces no funcionales en Java
- El método stream () no funciona en android
- Kotlin: safe lambdas (no hay fugas de memoria)?
- ¿Java 8 funciona en Android api 24 y superior ¿O puede utilizar en api menor?
- Retrolambda $ Lambda no encontrado
- ¿Hay alguna manera de utilizar interfaces funcionales Java 8 en la API de Android por debajo de 24?
- NoClassDefFoundError cuando uso lambda para recorrer String array
Lambdas no permiten _
como un nombre de parámetro, pero lo hacen las construcciones existentes.
De JLS 15.27.1. Lambda Parámetros :
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 la variable _ en cualquier contexto. Las versiones futuras del lenguaje de programación Java pueden reservar este nombre como una palabra clave y / o darle semántica especial.
Yo sugeriría renombrar los parámetros a __
, $
, o para ahorrar espacio, ya que ya está usando unicode, _
(aunque quizás este último es un abuso lingüístico – no sé para qué se destina ese punto de código real).
Antes de Java 8, un solo guión bajo _
era un identificador válido. A partir de Java 8, el subrayado no está permitido, para permitir la posibilidad futura de que sea algo distinto de un identificador ordinario. Vea este mensaje de Brian Goetz para la explicación.
El uso de un guión bajo en código existente (pre-lambda) generará una advertencia, pero el uso de un guión bajo como un nombre de parámetro formal lambda generará un error. Como dijo Brian, "ya que no existe un código con lambdas".
En su ejemplo, el parámetro formal _
en su clase interna anónima es el código legal, aunque debería generar una advertencia. ¡Refactorizar este código en un lambda que usa _
lo hará ilegal! Dado que IntelliJ IDEA está refactorizando este código, debe tener en cuenta esta regla, y debería ofrecer cambiar el nombre del parámetro a otra cosa.
Esto podría ser visto como un error, o al menos una necesidad de una mejora, en el mecanismo de refactorización de IDEA.