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。 但我无法正确理解这些方法。

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

它们指的是相同的function,但是以不同的方式编写。 第一种是调用接受OnClickListener对象的setOnClickListener()函数的典型方法。

第二个使用lambdaexpression式。 它的工作原理是因为View.OnClickListener是用Java定义的SAMtypes ,Kotlin支持SAM转换 。

就像Java 8一样,Kotlin支持SAM转换。 这意味着只要接口方法的参数types与Kotlin函数的参数types匹配,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转换提供了一种在Kotlin中编写干净代码的方法,该代码与Java交互。

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

在编译之后,两者都将生成相同的字节码,但在编写时它将通过单行实现提供更多可读性。

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

示例: source

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

如果您的界面只有一种方法。

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

你可以像这样把它写成Lambda。

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

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

在Kotlin中,lambdaexpression式与Java不同。

Kotlin lambdaexpression式示例: source

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

上面的函数variables可以像这样调用:

 val addedValue: Int = add(5, 5) 

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

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

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

您可以在Kotlin文档中看到:

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

实际上,您正在kotlin中编写lambda,稍后它将转换为java接口。 所以两种方法都不同。 但是当谈到执行时两者都是一样的。 它不会影响编译时间,所以总是建议使用lambda。

希望能帮助到你 :)