Kotlin SAM 转换改进

SAM 转换改进 是 Kotlin 语言在支持Java 接口函数式调用(Single Abstract Method,简称 SAM)方面做的增强和优化。下面我详细讲解:


🧠 1. 什么是 SAM(Single Abstract Method)

SAM 接口指的是那种只定义了一个抽象方法的接口,像 Java 里的:

1
2
3
interface Runnable {
void run();
}

在 Java 中可以这样写:

1
Runnable r = () -> System.out.println("run");

Kotlin 也支持这种简写方式,这就是 SAM 转换


✅ 2. Kotlin 的 SAM 转换(改进前)

在 Kotlin 的早期版本里:

  • SAM 转换 只对 Java 的接口生效。
  • Kotlin 自己定义的接口,即使只有一个抽象方法,也不支持 SAM 转换

示例(仅对 Java 接口有效):

1
val thread = Thread { println("Running in thread") } // ✅ Kotlin 自动帮你转成 Runnable

🚀 3. SAM 转换改进:支持 Kotlin 自定义函数接口

从 Kotlin 1.4 开始,SAM 转换被扩展到 Kotlin 自己定义的接口 —— 但有前提条件:

  • 必须标注为 fun interface(函数接口)

示例:

1
2
3
4
5
6
7
fun interface Action {
fun run()
}

fun doAction(action: Action) {
action.run()
}

现在可以像 Java lambda 那样使用了:

1
doAction { println("Action running") } // ✅ SAM 转换生效

🔍 4. 总结:SAM 转换改进了什么?

版本前 Kotlin 自定义接口不支持 SAM 转换(只能用匿名类)
Kotlin 1.4+ 支持使用 fun interface 实现 SAM 转换,像 Java lambda 那样简洁

✅ 5. 使用建议

  • 如果你要让 Kotlin 支持 lambda 表达式形式调用你写的接口,请用 fun interface
  • Kotlin 也建议尽量用函数类型((T) -> R)代替接口,但当需要 Java 兼容时 fun interface 更合适。

💡 示例对比总结

1
2
3
4
5
6
7
8
9
10
11
// Java 的 SAM 接口
Thread { println("Hello") } // ✅ Kotlin 自动转换成 Runnable

// Kotlin 自定义函数接口
fun interface MyCallback {
fun call()
}
fun run(cb: MyCallback) { cb.call() }

// 使用 lambda
run { println("Called!") } // ✅ Kotlin 1.4+ 支持

如果你正在用某个库,比如 Retrofit、RxJava、或协程等,想知道它有没有用到 SAM 或如何简化代码,我也可以帮你分析实际场景。需要吗?