Kotlin - 引用操作符 ::

一、概念

将类、函数、属性、构造函数等程序元素转化为可传递的引用对象,就像给这些元素贴上标签,方便在代码中灵活调用。

1.1 使用场景

不能引用局部函数、匿名函数和 Lambda 表达式 ,这些都属于不可引用的实体,如果强行引用,编译时会报错。

|--------|------------------------------------------------------------------|
| 类引用 | 很多时候需要传入 Java 的 Class 对象,通过【类名::class.java】来转换。 |
| 函数引用 | 将函数作为参数传递或赋值给变量,实现函数式编程的高阶特性。极大地增强了代码的灵活性与可扩展性,方便进行函数组合、策略模式等设计。 |
| 属性引用 | 获取属性的 getter 或 setter,实现对属性的间接访问与操作。这在数据绑定、属性监听等场景中十分实用。 |
| 构造函数引用 | 创建对象的工厂函数,便于根据不同需求动态创建对象。在对象池管理、依赖注入等场景中发挥重要作用。 |

1.2 KClass

通过【类名::class】获取 Kotlin 特有的类描述对象,它提供了更丰富的元信息,如simpleName(类名)、qualifiedName(完整类名)、isData(是否为数据类)等,这些额外信息使得在 Kotlin 中进行反射操作和类型处理更加便捷和强大,充分体现了 Kotlin 在语言设计上对开发者的友好和对现代编程需求的支持。

二、使用

2.1 类引用(类名::class.java)

Kotlin 复制代码
retrofit.create(ApiService::class.java)

2.2 函数引用

2.2.1 静态引用(类名::函数名)

静态引用在调用时,需要传入一个接收者对象。

Kotlin 复制代码
class Calculator {
    fun add(a: Int, b: Int): Int = a + b
}
val unboundAdd: Calculator.(Int, Int) -> Int = Calculator::add
val calculator = Calculator()
val result = unboundAdd(calculator, 2, 3)
println(result)  // 输出5

2.2.2 绑定引用(实例名::函数名)

绑定引用已经关联到了特定的实例,在调用时不需要再重复传递接收者对象。

Kotlin 复制代码
class Calculator {
    fun add(a: Int, b: Int): Int = a + b
}
val calculator = Calculator()
val boundAdd: (Int, Int) -> Int = calculator::add
val result = boundAdd(2, 3)
println(result)  // 输出5

2.2.3 顶层函数绑定引用(::函数)

Kotlin 复制代码
fun isEven(number: Int): Boolean = number % 2 == 0
val numbers = listOf(1, 2, 3, 4, 5, 6)
val evens = numbers.filter(::isEven)
println(evens)  // 输出[2, 4, 6]

2.3 属性引用(类名::属性名)

Kotlin 复制代码
class Person(
    val name: String,
    var age: Int
)

val nameGetter: (Person) -> String = Person::name
val person = Person("Alice", 30)
println(nameGetter(person))  // 输出Alice

val ageSetter: (Person, Int) -> Unit = Person::age
ageSetter(person, 31)
println(person.age)  // 输出31

2.4 构造函数引用(::类名)

java 复制代码
class User(val name: String)

val userFactory: (String) -> User = ::User
val newUser = userFactory("Bob")
println(newUser.name)  // 输出Bob

三、优化调用场景

3.1 简化 Lambda 表达式,提升可读性

函数引用是对已存在的具名函数的引用,不会像 Lambda 每次使用时都创建匿名内部类对象,从而减少了对象创建的开销。

Kotlin 复制代码
val strings = listOf("apple", "banana", "cherry")
//一般使用
val lengths = strings.map { it.length }
//优化后使用
val lengths = strings.map(String::length)

3.2 反射

Kotlin 复制代码
class Animal {
    fun makeSound() { println("Some sound") }
}
Kotlin 复制代码
fun main() {
    val className = "Animal"
    val kClass = Class.forName(className).kotlin
    val instance = kClass.constructors.first().call()
    val method = kClass.memberFunctions.find { it.name == "makeSound" }
    method?.call(instance)
}
相关推荐
李堇8 小时前
android滚动列表VerticalRollingTextView
android·java
lxysbly9 小时前
n64模拟器安卓版带金手指2026
android
游戏开发爱好者812 小时前
日常开发与测试的 App 测试方法、查看设备状态、实时日志、应用数据
android·ios·小程序·https·uni-app·iphone·webview
王码码203512 小时前
Flutter for OpenHarmony 实战之基础组件:第三十一篇 Chip 系列组件 — 灵活的标签化交互
android·flutter·交互·harmonyos
黑码哥13 小时前
ViewHolder设计模式深度剖析:iOS开发者掌握Android列表性能优化的实战指南
android·ios·性能优化·跨平台开发·viewholder
亓才孓13 小时前
[JDBC]元数据
android
独行soc13 小时前
2026年渗透测试面试题总结-17(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
金融RPA机器人丨实在智能13 小时前
Android Studio开发App项目进入AI深水区:实在智能Agent引领无代码交互革命
android·人工智能·ai·android studio
科技块儿13 小时前
利用IP查询在智慧城市交通信号系统中的应用探索
android·tcp/ip·智慧城市
独行soc14 小时前
2026年渗透测试面试题总结-18(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮