Diferencia entre los methods de OnclickListener en Kotlin

Estoy aprendiendo Kotlin. Antes de eso, he trabajado con Java para Android Development. Kotlin es un gran lenguaje para aprender. Tengo una confusión cuando estaba usando setOnClickListener(View.OnClickListener) . He visto dos pistas sobre Android Studio.

imagen

Sé cómo trabajar o definir ambos.

La primera forma de implementar OnClickListerner

  send_button.setOnClickListener(object : View.OnClickListener{ override fun onClick(p0: View?) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } }) 

y esta es la segunda forma de implementar OnClickListener

  send_button.setOnClickListener { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } 

Entiendo que el segundo método se base en lambda. Pero no puedo entender correctamente estos methods.

Entonces, mi pregunta es: ¿Cuál es la diferencia entre esos methods? Si difieren, ¿cuál es mejor y por qué?

Se refieren a la misma function pero están escritos de manera diferente. El primero es la forma típica de invocar la function setOnClickListener() que acepta un object OnClickListener .

El segundo hace uso de la expresión lambda. Funciona porque View.OnClickListener es un tipo de SAM definido en Java y Kotlin admite las conversiones de SAM .

Al igual que Java 8, Kotlin admite conversiones de SAM. Esto significa que los literales de function Kotlin se pueden convertir automáticamente en implementaciones de interfaces Java con un único método no pnetworkingeterminado, siempre que los types de parameters del método de interfaz coincidan con los types de parameters de la function Kotlin.

Supongamos que tiene una interfaz definida en Java como esta:

 public class Example { public interface SingleMethodInterface { int length(String text); } public static void set(SingleMethodInterface sam) {} } 

Luego, puede llamar a la function set() de las dos maneras siguientes en Kotlin:

 //Passing a function type which accept a `String` and return an `Int` val length: (String) -> Int = { it.length } Example.set(length) //or Example.set { it.length } //Passing an object which implements `SingleMethodInterface` val length2: Main.SingleMethodInterface = object: Main.SingleMethodInterface { override fun length(text: String): Int { return text.length } } Example.set(length2) 

En resumen, la conversión SAM proporciona una forma de escribir código limpio en Kotlin que interopera con Java.

Tu pregunta: ¿Cuál es la diferencia entre esos methods? Si difieren, ¿cuál es mejor y por qué?

Después de la compilation, ambos producirán el mismo bytecode, pero al escribirlo le dará más legibilidad mediante la implementación de una sola línea.

La gran característica de Java 8 son las expresiones Lambda. Con Lambda puedes escribir código Java más simple. El aspecto feo del código cambió ligeramente por esta característica.

Ejemplo: fuente

Puede escribir el Método único abstracto (SAM) como lambda.

Si su interfaz tiene un único método.

 public interface StateChangeListener { public void onStateChange(State oldState, State newState); } 

Puedes escribirlo así como Lambda.

 stateOwner.addStateListener( (oldState, newState) -> System.out.println("State changed") ); 

Pero ambos methods son los mismos, pero se puede ver que el segundo es tan simple y se elimina la implementación fea.

En Kotlin, las expresiones lambda son diferentes de Java.

Ejemplo de expresión de Kotlin lambda : fuente

 val add: (Int, Int) -> Int = { a, b -> a + b } 

La variable de function anterior se puede llamar así:

 val addedValue: Int = add(5, 5) 

Esto le devolverá el valor agregado de dos integers.

En este ejemplo, puede ver (Int, Int) -> Int , esto se llama function lambda en Kotlin.

Así que las funciones de Kotlin lambda y Java lambda son completamente diferentes.

Puedes ver en los Documentos de Kotlin:

Al igual que Java 8, Kotlin admite conversiones de SAM. Esto significa que los literales de function Kotlin se pueden convertir automáticamente en implementaciones de interfaces Java con un único método no pnetworkingeterminado, siempre que los types de parameters del método de interfaz coincidan con los types de parameters de la function Kotlin.

En realidad, estás escribiendo el lambda en kotlin, luego se convertirá a la interfaz de java. Entonces ambos methods son diferentes. Pero cuando se trata de ejecución, ambos son lo mismo. No afectará el time de compilation así que siempre se sugiere usar lambda.

Espero eso ayude 🙂

  • Sirve favicon.ico y otros files estáticos con VertX
  • Llamar a REST api en el emulador de Android hace que la aplicación se cuelgue
  • Carga GIF usando la versión 4.2.0 de deslizamiento en Kotlin
  • ¿Por qué el código de byte de Kotlin hace reference a java.util.function.BiConsumer?
  • Usar bibliotecas de UI de terceros con TornadoFX
  • ¿Es posible pasar la reference al elemento i-ésimo de una matriz primitiva?
  • Gradle no puede resolver references de otro module
  • Referencia no resuelta: campo en Kotlin
  • ¿Es posible ejecutar el complemento de grado kotlin usando jdk 7?
  • ¿Hay una MutableList instanciable en Kotlin, evitando Java api?
  • ¿Cómo puedo saber si un número es una potencia de 10 en Kotlin o Java?