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。
希望它有助于:)