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 🙂

  • ¿Accediendo a la function de extensión estática de otra class en Kotlin?
  • cuándo utilizar lateinit, init block y el object complementario. Kotlin
  • ¿Por qué todavía es necesario lanzar el tipo aunque ya se haya asegurado en este ejemplo?
  • Conversión de código de Java a Kotlin en Android Studio
  • Incrementos causa falla de compilation
  • ¿Cómo puedo crear un método "estático" para enum en Kotiln?
  • Cómo almacenar BigDecimal en Firebase?
  • Error de compilation después de actualizar a Android Studio 3.0 con Kotlin
  • ¿Por qué una propiedad tipada genérica se puede anular?
  • ¿Lista floja en kotlin?
  • Obligatorio <Objeto> y encontrado <Objeto>?