Loading

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、编译器会对被扩展类的调用转换为对生成的静态方法的调用。

posted @ 2024-01-29 15:44  妖久  阅读(67)  评论(0编辑  收藏  举报