Kotlin 扩展方法(Extension Functions)使用详解

用更优雅的语法,为现有类添加新功能

一、扩展方法原理

本质 :扩展方法是一种 静态分发 的语法糖,通过 接收者类型(Receiver Type) 为现有类(包括第三方库或系统类)添加新方法,不会侵入原类代码

编译逻辑

kotlin 复制代码
// 定义扩展方法
fun String.addExclamation() = "$this!"  

// 编译后等价于:
public static String addExclamation(String $this) {
  return $this + "!";
}

关键特性

  • 扩展方法优先级低于类原有方法(同名方法以原类方法为准)
  • 扩展方法无法访问私有成员(只能访问 public/protected 成员)
  • 支持泛型空安全 (如 fun String?.safePrint()

二、使用场景

1. 增强第三方库或系统类功能

kotlin 复制代码
// 为 RecyclerView 添加快速设置 Adapter 的方法
fun RecyclerView.setup(adapter: RecyclerView.Adapter<*>) {
    this.adapter = adapter
    this.layoutManager = LinearLayoutManager(context)
}

2. 替代 Java 工具类,提升代码可读性

kotlin 复制代码
// 替代 DateUtils.formatTimestamp(time) → time.formatTimestamp()
fun Long.formatTimestamp(): String = SimpleDateFormat("yyyy-MM-dd").format(Date(this))

3. 链式调用,简化逻辑

kotlin 复制代码
// 字符串处理链
val result = "hello"
    .capitalize()      // 原方法
    .addExclamation()  // 扩展方法
    .repeat(2)         // 原方法
println(result)        // 输出 "Hello!Hello!"

4. 空安全处理

kotlin 复制代码
// 安全处理可空字符串
fun String?.safeLength(): Int = this?.length ?: 0
val length = nullableString.safeLength()

5. DSL 设计(如布局构建)

kotlin 复制代码
// 自定义 View 的 DSL
fun Context.myCustomView(init: MyCustomView.() -> Unit): MyCustomView {
    return MyCustomView(this).apply(init)
}

三、示例代码

场景 1:为基本类型添加功能

kotlin 复制代码
// 为 Int 添加是否为偶数的判断
fun Int.isEven(): Boolean = this % 2 == 0  
println(4.isEven())  // 输出 true

// 为 List 添加快速交换元素的方法
fun <T> List<T>.swap(index1: Int, index2: Int): List<T> {
    val mutableList = this.toMutableList()
    mutableList[index1] = mutableList[index2].also { mutableList[index2] = mutableList[index1] }
    return mutableList.toList()
}
val list = listOf("A", "B", "C")
println(list.swap(0, 2))  // 输出 [C, B, A]

场景 2:Android 视图扩展

kotlin 复制代码
// 为 View 添加防抖点击监听
fun View.setOnSingleClickListener(debounceTime: Long = 500, action: (View) -> Unit) {
    var lastClickTime = 0L
    setOnClickListener { view ->
        val currentTime = System.currentTimeMillis()
        if (currentTime - lastClickTime > debounceTime) {
            action(view)
            lastClickTime = currentTime
        }
    }
}

// 使用
button.setOnSingleClickListener {
    showToast("防止重复点击")
}

场景 3:伴生对象扩展

kotlin 复制代码
class MyClass { companion object }

// 为伴生对象添加方法
fun MyClass.Companion.createFromJson(json: String): MyClass = ...  
val instance = MyClass.createFromJson("{...}")

场景 4:扩展属性

kotlin 复制代码
// 为 String 添加反转属性(注意:扩展属性不能有幕后字段)
val String.reversed: String get() = this.reversed()
println("abc".reversed)  // 输出 "cba"

四、注意事项

  1. 避免滥用:过度扩展会使代码难以维护,优先考虑是否应该通过继承或组合实现

  2. 作用域控制

    • 使用 import com.example.util.* 导入特定扩展
    • 通过 @file:JvmName("StringUtils") 管理扩展文件
  3. 与 Java 互操作

    java 复制代码
    // Java 中调用 Kotlin 扩展方法
    StringUtilKt.addExclamation("hello"); 
  4. 性能影响:扩展方法在编译后转为静态方法,无额外性能损耗

通过扩展方法,让 Kotlin 代码更简洁、更富有表现力! 🚀

更多分享

  1. 一文吃透Kotlin中冷流(Clod Flow)和热流(Hot Flow)
  2. 一文带你吃透Kotlin协程的launch()和async()的区别
  3. Kotlin 委托与扩展函数------新手入门
  4. Kotlin 作用域函数(let、run、with、apply、also)的使用指南
  5. 一文带你吃透Kotlin中 lateinit 和 by lazy 的区别和用法
相关推荐
&岁月不待人&8 小时前
⏺ Android 录屏缩放异常排查:Pixel 3 XL 上的完美风暴
android
a3158238068 小时前
Android 大图显示策略优化显示(一)
android·算法·图片加载·大图片
tangweiguo030519878 小时前
从零开始:在 Windows 上使用命令行编译 Android .so 动态库(NDK + CMake + Ninja)
android
阿波罗尼亚8 小时前
Tcp SSE Utils
android·java·tcp/ip
知行合一。。。12 小时前
Python--03--函数入门
android·数据库·python
大、男人13 小时前
python之contextmanager
android·python·adb
不法15 小时前
java查看安卓证书信息
android
儿歌八万首15 小时前
Jetpack Compose 动画实战:让你的 UI 动起来
android·kotlin·动画·compose
千里马学框架15 小时前
如何改进车载三分屏SplitScreen启动交互方式?
android·智能手机·分屏·aaos·安卓framework开发·车载开发·3分屏
iOS阿玮16 小时前
“死了么”App荣登付费榜第一名!
uni-app·app·apple