目录

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 的区别和用法
本文是转载文章,点击查看原文
如有侵权,请联系 xyy@jishuzhan.net 删除
相关推荐
大胃粥18 分钟前
Android V app 冷启动(8) 动画结束
android
ufo00l42 分钟前
Kotlin在Android中有哪些重要的应用和知识点是需要学习或者重点关注的
android
AJi42 分钟前
Android音视频框架探索(二):Binder——系统服务的通信基础
android·ffmpeg·音视频开发
tjsoft1 小时前
Nginx配置伪静态,URL重写
android·运维·nginx
努力学习的小廉2 小时前
【C++11(中)】—— 我与C++的不解之缘(三十一)
android·java·c++
tangweiguo030519872 小时前
打破界限:Android XML与Jetpack Compose深度互操作指南
android·kotlin·compose
Watink Cpper3 小时前
[MySQL初阶]MySQL(8)索引机制:下
android·数据库·b树·mysql·b+树·myisam·innodedb
一起搞IT吧3 小时前
高通camx IOVA内存不足,导致10-15x持续拍照后,点击拍照键定屏无反应,过一会相机闪退
android·数码相机
前行的小黑炭5 小时前
设计模式:为什么使用模板设计模式(不相同的步骤进行抽取,使用不同的子类实现)减少重复代码,让代码更好维护。
android·java·kotlin
ufo00l6 小时前
2025年了,Rxjava解决的用户痛点,是否kotlin协程也能解决,他们各有什么优缺点?
android