我正在学习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。但我无法正确理解这些方法。
所以,我的问题是:这些方法有什么区别?如果它们不同,哪一个更好,为什么?
答案 0 :(得分:5)
它们指的是相同的功能,但是以不同的方式编写。第一种是调用接受setOnClickListener()
对象的OnClickListener
函数的典型方法。
第二个使用lambda表达式。它有效,因为View.OnClickListener
是Java中定义的SAM type,Kotlin支持SAM conversions。
就像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转换提供了一种在Kotlin中编写干净代码的方法,该代码与Java交互。
答案 1 :(得分:3)
你的问题: 这些方法有什么区别?如果它们不同,哪一个更好,为什么?
编译之后,两者都会生成相同的字节码,但写入时会通过单行实现提供更多的可读性。
Java 8的强大功能是Lambda表达式。使用Lambda,您可以更简单地编写Java代码。这个功能略微改变了代码的丑陋外观。
示例:source
您可以将单一抽象方法(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 表达示例:source
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文档中看到:
就像Java 8一样,Kotlin支持SAM转换。这意味着 Kotlin函数文字可以自动转换为 使用单个非默认方法实现Java接口, 只要接口方法的参数类型匹配即可 Kotlin函数的参数类型。
实际上,您正在kotlin中编写lambda,稍后它将转换为java接口。所以两种方法都不同。但是当谈到执行时两者都是一样的。它不会影响编译时间,所以总是建议使用lambda。
希望有所帮助:)