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 的区别和用法
相关推荐
weixin_4407841126 分钟前
Android基础知识汇总
android·java·android studio
small-pudding1 小时前
Cocos Creator Android 热更新方案实践:逻辑更新、远程 Bundle 与线上回滚
android
00后程序员张1 小时前
iOS加固技术路线全面解析:Bitcode模式、源码模式与汇编模式对比及爱加密优势
android·汇编·ios·小程序·uni-app·cocoa·iphone
summerkissyou19871 小时前
android - 性能 - Perfetto - 内存分析教程及例子
android·性能
超开心~2 小时前
Android AAudio介绍及流程分析
android
取个名字太难了~2 小时前
最新手机外接相机实时传输 + 动态美颜完整项目源码
android·数码相机·智能手机·美颜·相机连接·demu
say_fall2 小时前
【Linux系统编程】文件操作基础:C标准库、系统调用、fd是什么和fd与FILE*的关系
android·linux·c语言
ii_best11 小时前
更新!移动端开发软件按键安卓版&手机助手v5.1.0上线!本地AI识别全面解锁,脚本开发再升级
android·人工智能·ios·按键精灵
方乐寺村12 小时前
s,使用libpng提升png图片的保存速度。接下来本文将阐述在Android中如何集成libpng,以及在使用过程中遇到的问题和最 ...
android
name好难取诶12 小时前
PHP 静态分析工具实战 PHPStan 和 Psalm 完全指南
android·开发语言·php