Kotlin擴充套件函式與屬性原理解析

妖久發表於2024-01-29

一、擴充套件函式

擴充套件函式可以方便地給現有類增加屬性和方法而不改動類地程式碼。

二、原理

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、擴充套件函式實際是一個靜態函式處於類的外部,而成員函式是類的內部函式。

相關文章