首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

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

  • 25-04-17 10:20
  • 3201
  • 11162
juejin.cn

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

一、扩展方法原理

本质:扩展方法是一种 静态分发 的语法糖,通过 接收者类型(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 List.swap(index1: Int, index2: Int): List { 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 的区别和用法
注:本文转载自juejin.cn的QING618的文章"https://juejin.cn/post/7487913431667507241"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top