UltimateDevil
UltimateDevil

Reputation: 2847

Difference between OnclickListener methods in Kotlin

I am learning Kotlin. Before that, I have worked with Java for Android Development. Kotlin is a great language to learn. I have a confusion while I was using setOnClickListener(View.OnClickListener). I have seen two hints on Android Studio.

image

I know how to work or define both of them.

The first way to implementing 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.
       }
   })

and this is the second way of implementing OnClickListener

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

I understand as far as the second method is based on lambda. But I can't have the proper understanding of these methods.

So, my question is: What is the difference between those methods? If they differ, which one is better and why?

Upvotes: 13

Views: 6090

Answers (2)

IntelliJ Amiya
IntelliJ Amiya

Reputation: 75778

Your Question: What is the difference between those methods? If they differ, which one is better and why?

After compilation, both will produce the same bytecode but while writing it will give you more readability by single line implementation.

The great feature of Java 8 is Lambda expressions. With Lambda you can write java code simpler. The ugly look of code slightly changed by this feature.

Example: source

You can write Single Abstract Method (SAM) as lambda.

If your interface has an only one method.

public interface StateChangeListener {

    public void onStateChange(State oldState, State newState);

}

You can write it as Lambda like this.

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

But both of the methods are same but you can see the second one is so simple and removed ugly implementation.

In Kotlin, lambda expressions are different from Java.

Kotlin lambda expression example: source

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

The above function variable can be called like this:

val addedValue: Int = add(5, 5)

This will return you the added value of two integers.

In this example you can see (Int, Int) -> Int, this is called lambda function in Kotlin.

So Kotlin lambda and Java lambda functions are completely different.

You can see in the Kotlin Docs:

Just like Java 8, Kotlin supports SAM conversions. This means that Kotlin function literals can be automatically converted into implementations of Java interfaces with a single non-default method, as long as the parameter types of the interface method match the parameter types of the Kotlin function.

Actually, you are writing the lambda in kotlin, later it will be converted to java interface. So both methods are different. But when it comes to execution both are same. It won't affect compile time so it's always suggested to use lambda.

Hope it helps :)

Upvotes: 5

BakaWaii
BakaWaii

Reputation: 6992

They refer to the same function but are written in different way. The first one is the typical way to invoke the setOnClickListener() function which accepts an OnClickListener object.

The second one make use of lambda expression. It works because View.OnClickListener is a SAM type defined in Java and Kotlin supports SAM conversions.

Just like Java 8, Kotlin supports SAM conversions. This means that Kotlin function literals can be automatically converted into implementations of Java interfaces with a single non-default method, as long as the parameter types of the interface method match the parameter types of the Kotlin function.

Suppose you have an interface defined in Java like this:

public class Example {
    public interface SingleMethodInterface {
        int length(String text);
    }

    public static void set(SingleMethodInterface sam) {}
}

Then, you can call set() function in the following two ways in 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)

In short, SAM conversion provide a way to write clean code in Kotlin which interop with Java.

Upvotes: 8

Related Questions