Kotlin中的OnclickListener方法之间的区别

我正在学习Kotlin。 在此之前,我曾与Java的Android开发工作。 Kotlin是一门伟大的语言学习。 我在使用setOnClickListener(View.OnClickListener) 。 我已经看到了Android Studio的两个提示。

图片

我知道如何工作或定义他们两个。

实现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. } }) 

这是实现OnClickListener的第二种方式

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

据我所知,第二种方法是基于lambda的。 但是我不能正确理解这些方法。

所以,我的问题是:这些方法有什么区别? 如果它们不同,哪一个更好,为什么?

他们指的是相同的功能,但以不同的方式写入。 第一个是调用接受OnClickListener对象的setOnClickListener()函数的典型方法。

第二个使用lambda表达式。 它的工作原理是View.OnClickListener是Java中定义的SAM类型 ,Kotlin支持SAM转换 。

就像Java 8一样,Kotlin支持SAM转换。 这意味着只要接口方法的参数类型与Kotlin函数的参数类型匹配,Kotlin函数文本就可以用一个非默认方法自动转换为Java接口的实现。

假设你有一个用Java定义的接口,如下所示:

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

然后,你可以在Kotlin中通过以下两种方式调用set()函数:

 //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) 

简而言之,SAM转换提供了一种在Java中与Kotlin编写干净的代码的方法。

你的问题: 这些方法有什么区别? 如果它们不同,哪一个更好,为什么?

编译之后,两者都会产生相同的字节码,但是在编写的时候,它会给你更多的单线实现的可读性。

Java 8的强大功能是Lambda表达式。 使用Lambda,您可以更简单地编写Java代码。 这个功能稍微改变了代码的丑陋外观。

例如: 来源

您可以将单一抽象方法(SAM)写为lambda。

如果你的接口只有一个方法。

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

你可以像这样写成Lambda。

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

但是这两种方法都是一样的,但是你可以看到第二个方法非常简单并且删除了丑陋的实现。

在Kotlin中,lambda表达式与Java不同。

Kotlin lambda表达式示例: 源代码

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

上面的函数变量可以这样调用:

 val addedValue: Int = add(5, 5) 

这将返回两个整数的附加值。

在这个例子中你可以看到(Int, Int) -> Int ,这在Kotlin中被称为lambda函数。

所以Kotlin lambda和Java lambda函数是完全不同的。

您可以在Kotlin Docs中看到:

就像Java 8一样,Kotlin支持SAM转换。 这意味着只要接口方法的参数类型与Kotlin函数的参数类型匹配,Kotlin函数文本就可以用一个非默认方法自动转换为Java接口的实现。

其实,你正在写kotlin的lambda,后来它会被转换成java接口。 所以两种方法都不一样 但是在执行时,两者都是一样的。 它不会影响编译时间,所以总是建议使用lambda。

希望它有助于:)