Kotlin扩展函数与属性原理解析
一、扩展函数
扩展函数可以方便地给现有类增加属性和方法而不改动类地代码。
二、原理
fun String.addTo(s: String): String{
return this + s
}
反编译:
@Metadata(
mv = {1, 6, 0},
k = 2,
d1 = {"\u0000\n\n\u0000\n\u0002\u0010\u000e\n\u0002\b\u0002\u001a\u0012\u0010\u0000\u001a\u00020\u0001*\u00020\u00012\u0006\u0010\u0002\u001a\u00020\u0001¨\u0006\u0003"},
d2 = {"addTo", "", "s", "app_releaseFlavorDebug"}
)
public final class TestKt {
@NotNull
public static final String addTo(@NotNull String $this$addTo, @NotNull String s) {
Intrinsics.checkNotNullParameter($this$addTo, "$this$addTo");
Intrinsics.checkNotNullParameter(s, "s");
return $this$addTo + s;
}
}
可以看出扩展函数实际上是生成了一个静态方法,并且将被扩展的类的对象传进了函数中。
由此我们可以知道:
我们在扩展函数中可以访问被扩展的类的函数与属性,但是不能访问私有的函数与属性,其访问权限与对象访问权限一致。
三、扩展属性
扩展属性提供了一种方法能通过属性语法进行访问的API来扩展。尽管它们被叫做属性,但是它们不能拥有任何状态,它不能添加额外的字段到现有的Java对象实例。
val String.lastChar: Char get() = this[length -1]
原理与扩展函数类似。
public static final char getLastChar(@NotNull String $this$lastChar) {
Intrinsics.checkNotNullParameter($this$lastChar, "$this$lastChar");
return $this$lastChar.charAt($this$lastChar.length() - 1);
}
四、伴生对象的扩展函数
class Test{
companion object{
}
}
fun Test.Companion.get() {
}
五、总结
1、我们在扩展函数中可以访问被扩展的类的函数与属性,但是不能访问私有的函数与属性,其访问权限与对象访问权限一致。
2、扩展函数不能被子类重写。
3、扩展函数实际是一个静态函数处于类的外部,而成员函数是类的内部函数。
4、编译器会对被扩展类的调用转换为对生成的静态方法的调用。