跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
Kotlinjava

Kotlin 扩展函数与属性详解及示例

综述由AI生成详细讲解了 Kotlin 中的扩展函数与扩展属性。扩展函数允许在不继承的情况下为现有类添加新方法,其底层实现为带有接收者参数的静态方法。文章涵盖了扩展函数的定义、导入方式、与 Java 的互调机制、工具函数写法以及不可重写的特性。同时介绍了扩展属性的 Getter/Setter 实现限制及可变性处理。通过具体代码示例展示了如何计算字符串末尾字符及集合连接操作,强调了扩展函数在提升代码可读性与简洁性方面的优势,并指出了其在访问私有成员和多态行为上的限制。

不羁发布于 2025/2/7更新于 2026/5/911 浏览
Kotlin 扩展函数与属性详解及示例

Kotlin 扩展函数与属性详解

前言

Kotlin 中的类扩展方法并不是在原类的内部进行拓展。通过反编译为 Java 代码可以发现,其原理是使用装饰模式,对源类实例的操作和包装。其实际相当于在 Java 中定义的工具类方法,并且该工具类方法是使用调用者为第一个参数的,然后在工具方法中操作该调用者。

理论上来说,扩展函数很简单,它就是一个类的成员函数,不过定义在类的外面。让我们来添加一个方法,来计算一个字符串的最后一个字符:

package strings

fun String.lastChar(): Char = get(this.length - 1)

要做的,就是把要扩展的类或者接口的名称,放到即将添加的函数前面。这个类的名称被称为接收者类型;用来调用这个扩展函数的对象,叫做接收者对象。

示意图

接收者类型是由扩展函数定义的,接收对象是该类型的一个实例。

可以像调用类的成员函数一样去调用这个函数:

println("Kotlin".lastChar())

从某种意义上说,现在已经为 String 类添加了自己的方法。不管 String 类是用 Java、Kotlin,或者像 Groovy 的其他 JVM 语言编写的,只要它会编译为 Java 类,就可以为这个类添加自己的扩展。

在这个扩展函数中,可以像其他成员函数一样用 this。也可以像普通的成员函数一样,省略它:

fun String.lastChar(): Char = get(this.length - 1)

注意,扩展函数并不允许打破它的封装性。和在类内部定义的方法不同的是,扩展函数不能访问私有的或者是受保护的成员。

导入和扩展函数

对于定义的一个扩展函数,它不会自动地在整个项目范围内生效。相反,如果要使用它,需要进行导入,就像其他任何的类或者函数一样。这是为了避免偶然性的命名冲突。Kotlin 允许用和导入类一样的语法来导入单个的函数:

import strings.lastChar
//星号导入
import strings.*

在 Java 中调用扩展函数

其实,扩展函数是静态函数,它把调用对象作为了它的第一个参数。调用扩展函数,不会创建适配的对象或者任何运行时的额外消耗。

这使得从 Java 中调用 Kotlin 的扩展函数变得非常简单:调用这个静态函数,然后把接收对象作为第一个参数传进去即可。假设它声明在一个叫做 StringUtil.kt 的文件中:

char   StringUtil.lastChar();
c
=
"Java"

和 Kotlin 版本比较起来,可读性略差。

作为扩展函数的工具函数

现在,可以写一个 joinToString 函数的终极版本了:

fun <T> Collection<T>.joinToString(
    separator: String = ", ",
    prefix: String = "",
    postfix: String = ""
): String {
    val result = StringBuilder(prefix)
    for ((index, element) in this.withIndex()) {
        if (index > 0) result.append(separator)
        result.append(element)
    }
    result.append(postfix)
    return result.toString()
}

因为扩展函数无非就是静态函数的一个高效语法糖,可以使用更具体的类型来作为接收者类型,而不是一个类。假设想要一个 join 函数,只能由字符串的集合来触发:

fun Collection<String>.join(
    separator: String = ", ",
    prefix: String = "",
    postfix: String = ""
): String {
    val result = StringBuilder(prefix)
    for ((index, element) in this.withIndex()) {
        if (index > 0) result.append(separator)
        result.append(element)
    }
    result.append(postfix)
    return result.toString()
}

如果是用其他类型的对象列表来调用会报错。

不可重写的扩展函数

扩展函数并不是类的一部分,它是声明在类之外的。扩展函数并不存在重写,因为 Kotlin 会把它们当做静态函数对待。这意味着如果子类定义了同名的成员函数,将优先调用成员函数而非扩展函数。

扩展属性

val String.lastChar: Char
    get() = get(this.length - 1)

和扩展函数一样,扩展属性也像接收者的一个普通成员属性一样。

这里必须定义 getter 函数,因为没有支持字段,因此没有默认的 getter 的实现。同理,初始化也不可以,因为没有地方存储初始值。

如果在 StringBuilder 上定义一个相同的属性,可以置为 var,因为 StringBuilder 的内容是可变的:

var StringBuilder.lastChar: Char
    get() = get(length - 1)
    set(value) {
        this.setCharAt(length - 1, value)
    }

可以像访问成员属性一样访问它:

println("Kotlin".lastChar)
val sb = StringBuilder("Kotlin?")
sb.lastChar = '!'
println(sb)

注意,当需要从 Java 中访问扩展属性的时候,应该显式地调用它的 getter 函数:StringUtil.getLastChar("Java")。

总结

Kotlin 的扩展函数和属性提供了一种强大的方式来增强现有类的功能,而无需修改其源代码或继承新类。它们本质上被编译为静态方法,具有良好的性能且与 Java 互操作无缝。开发者在使用时需注意扩展函数无法访问私有成员,且不存在多态重写机制。合理利用扩展函数可以显著提升代码的可读性和简洁性,特别是在处理标准库类型或第三方库时。在实际项目中,建议将常用的扩展函数组织在独立的工具包中,并通过明确的导入语句管理依赖,以避免命名冲突并维护代码的清晰度。

目录

  1. Kotlin 扩展函数与属性详解
  2. 前言
  3. 导入和扩展函数
  4. 在 Java 中调用扩展函数
  5. 作为扩展函数的工具函数
  6. 不可重写的扩展函数
  7. 扩展属性
  8. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • GPT-5.5 超高智商模型1元抵1刀ChatGPT中转购买
  • 代充Chatgpt Plus/pro 帐号了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 成为顶尖白帽黑客的成长路径与核心技能解析
  • 前端无障碍性实战:构建包容性的 Web 体验
  • 数据结构:八种常见排序算法
  • Python 核心应用领域与开发环境配置详解
  • 用老 Mac 跑本地 AI:OpenClaw 环境一键搭建
  • OpenClaw 开源 AI Agent 框架技术解析与架构设计
  • 宇树 G1 机器人强化学习训练环境搭建与奖励函数解析
  • MySQL 约束详解:非空、主键、外键的核心作用与实战
  • 大模型日报:今日必读的 8 篇前沿论文
  • Python 爬虫实战:链家二手房数据抓取与分析
  • 基于 YOLOv8/v11 与 LLM 的 Web 目标检测及表情识别系统
  • llama.cpp Docker 镜像国内加速下载地址
  • AIGC 下一站:文生视频技术发展与伦理风险
  • RESTful API 接口设计规范与实战
  • 前端实战:如何实现用户回到上次阅读位置
  • Arduino 6.5 寸轮毂电机智能动态跟随机器人底盘设计与实现
  • Ubuntu 22.04 生产环境部署 FastAPI + Uvicorn + Nginx 实战
  • Flutter inappwebview_cookie_manager 在鸿蒙系统下的适配与 Cookie 隔离实践
  • Java Web 学习:前端 HTML 核心知识点总结
  • VS Code 主流 AI 编程插件功能对比与选型

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online