Kotlin的fun interface xx 2025年07月13日 目次 当我们写Java时有这么一种情况,需要用到回调,但是回调中只有一个方法, 这时候的写法可以更简便,举个例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class SAMJava {
public static void main ( String [] args ) {
// 写法1
execute ( new BlockJava () {
@Override
public void invoke () {
// do something
}
});
}
static void execute ( BlockJava blockJava ) {
blockJava . invoke ();
}
}
interface BlockJava {
void invoke ();
}
上面是Java中传递匿名对象最最普通的写法,换用lambda的形式可以写成:
1
2
3
4
// 写法2
execute (() -> {
// do something
});
看起来干净了很多,这就是SAM(Single Abstract Method)。要说有什么作用,就是让代码看起来很干净。这也是有限制的,只能是接口类中有一个方法需要实现的时候,当接口的中有两个方法就不行了,只能老老实实用的用方法1.
这都是在Java中,Kotlin中有些不同。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
object SAMKt {
@JvmStatic
fun main ( args : Array < String >) {
// 写法1
execute ( object : BlockKotlin {
override fun invoke () {
// do something
}
})
}
fun execute ( blockJava : BlockKotlin ) {
blockJava . invoke ()
}
}
interface BlockKotlin {
fun invoke () // void fiinish();
}
匿名对象的形式当然是可以的,如果想换成Kotlin中lamdbas的写法,代码检查就是提示错误。
1
2
3
4
// 写法2,报错
execute {
// do something
}
Kotlin中能不能呢,能。但有点不同,你需要声明接口是fun interface:
1
2
3
fun interface BlockKotlin {
fun invoke () // void fiinish();
}
这时候还会提示你可以写成了写法2。 除此之外,还有一种写法。我们知道Kotlin是有高阶函数的,高阶函数可以做这事。
1
2
3
4
5
6
fun execute2 ( block : () -> Unit ) {
block ()
}
execute2 { }
这样也是没问题的。
参考 # 上篇:重建时Fragment发生了什么
下篇:协变和逆变