Kotlin扩展函数、扩展属性
扩展函数 扩展属性 kotlin
·
在Java中,常常会使用到诸如 StringUtil、DateUtil 等工具类,代码写起来比较长,并且调用方式不够简单直接。
在Java中,无法给String类添加自定义方法,因为String类是final,同时是JDK内置的基础类,不能修改。
一般的做法是开发一个StringUtil类,在里面封装相关的String操作方法,而不是修改或继承String类。
在Kotlin中,可以自由扩展任何类的方法和属性。
在不修改原类的情况下,Kotlin能一个类扩展新功能,同时无需继承该类。
扩展函数
给String类扩展两个函数
/**
* 给 String 扩展一个 firstChar() 函数
*/
fun String.firstChar(): String {
if (this.isEmpty()) return ""
return this[0].toString()
}
/**
* 给 String 扩展一个 lastChar() 函数
*/
fun String.lastChar(): String {
if (this.isEmpty()) return ""
return this[this.length -1].toString()
}
// 测试扩展函数
fun main(args: Array<String>) {
println("xyz".firstChar()) // 输出:x
println("xyz".lastChar()) // 输出:y
println("扩展函数".firstChar()) // 输出:扩
println("扩展函数".lastChar()) // 输出:数
}
扩展的实现原理
扩展函数和扩展属性的本质是以静态导入的方式来实现的。
在IDEA中查看Kotlin代码Bytecode 以及反编译成等价的Java代码:
Tools / Kotlin / Show Kotlin Bytecode ,可以查看Kotlin代码Bytecode;
然后选择Decompile按钮,就可以查看对应的Java代码了。
- String 类的扩展函数 firstChar() 对应的Java代码:
@NotNull
public static final String firstChar(@NotNull String $this$firstChar) {
Intrinsics.checkNotNullParameter($this$firstChar, "$this$firstChar");
CharSequence var1 = (CharSequence)$this$firstChar;
boolean var2 = false;
return var1.length() == 0 ? "" : String.valueOf($this$firstChar.charAt(0));
}
给List类扩展一个函数
/**
* 给 List 扩展一个 filterX() 函数
*
* predicate: (T) -> Boolean 是函数类型的参数
*/
fun <T> List<T>.filterX(predicate: (T) -> Boolean): MutableList<T> {
val result = ArrayList<T>()
this.forEach { // this 指向调用者对象
if (predicate(it)) { // 满足判断条件
result.add(it)
}
}
return result
}
// 测试扩展函数
fun testListFilterX(): Unit {
val list = listOf(1,2,3,4,5,6,7)
val result = list.filterX { it % 3 == 0}
println(result) // 输出:[3, 6]
}
扩展属性
给 MutableList 扩展两个属性 firstElement和lastElement:
/**
* 给 MutableList 扩展一个属性 firstElement
*/
var <T> MutableList<T>.firstElement: T?
get() {
return if (this.isNotEmpty()) this[0] else null
}
set(value) {
if (value != null) {
if (this.isNotEmpty()) {
this[0] = value
} else {
add(value)
}
}
}
/**
* 给 MutableList 扩展一个属性 lastElement
*/
var <T> MutableList<T>.lastElement: T?
get() {
return if (this.isNotEmpty()) this[this.size -1] else null
}
set(value) {
if (value != null) {
if (this.isNotEmpty()) {
this[this.size -1] = value
} else {
add(value)
}
}
}
// 测试扩展属性
fun testMutableListExp(): Unit {
val list1 = mutableListOf<Int>()
println(list1) // 输出:[]
println(list1.firstElement) // 输出:null
println(list1.lastElement) // 输出:null
list1.apply {
add(1)
add(2)
add(3)
add(4)
add(5)
}
println(list1) // 输出:[1, 2, 3, 4, 5]
println(list1.firstElement) // 输出:1 . 调用了getter函数
println(list1.lastElement) // 输出:5
list1.firstElement = -1 // 调用了setter函数
list1.lastElement = 55
println(list1) // 输出:[-1, 2, 3, 4, 55]
}
扩展属性的实现原理
在IDEA中:选择 Tools / Kotlin / Show Kotlin Bytecode ,然后点击
Decompile按钮,查看对应的Java代码。
MutableList 的扩展属性 firstElement 对应的Java代码:
@Nullable
public static final Object getFirstElement(@NotNull List $this$firstElement) {
Intrinsics.checkNotNullParameter($this$firstElement, "$this$firstElement");
Collection var1 = (Collection)$this$firstElement;
boolean var2 = false;
return !var1.isEmpty() ? $this$firstElement.get(0) : null;
}
public static final void setFirstElement(@NotNull List $this$firstElement, @Nullable Object value) {
Intrinsics.checkNotNullParameter($this$firstElement, "$this$firstElement");
if (value != null) {
Collection var2 = (Collection)$this$firstElement;
boolean var3 = false;
if (!var2.isEmpty()) {
$this$firstElement.set(0, value);
} else {
$this$firstElement.add(value);
}
}
}
扩展中的this关键字
- 在扩展函数中,以及带接收者的函数字面值中,this关键字代表调用函数时,在点号“.”之前的指定的对象实例。
- 在类的成员函数中,this指向这个类的当前实例对象。
- 如果this没有限定符,那么它指向包含当前代码的最内层范围。可以使用标签限定符,使this指向其他范围。
更多推荐



所有评论(0)