Kotlin擴展方法

前言

帶你深刻理解Kotlin擴展函數和java的關係java

環境以及工具

Android Studio 3.3git

擴展函數(本kt文件中擴展方法)

//-----------------------擴展函數(本類中擴展方法)-------------------------------------
class Test1 {
    var name: String = "boyi.chen"
}
//Test1:接收器類型(receiver type)
//this:  接收器對象(receiver object)
fun Test1.temp() {
    println("增長擴展函數,打印擴展類的屬性name=${this.name}")
}

fun main(args: Array<String>) {
  //-----------------------擴展函數(本kt文件)-------------------------------------
    Test1().temp()//輸出結果-------------------------增長擴展函數-------------------------
}
複製代碼

在這個例子中,Test1是接收器類型,Test1()和this是接收器對象,在這個擴展函數中,你可使用this直接訪問你擴展的類型的函數和屬性,就像定義在這個類中的方法同樣調用。github

這個例子若是看不懂,不要緊,文末已經給出答案。bash

擴展函數(其餘包下的kt文件)

package com.boy.learning.kotlinlearningtravel.extensions.utils

class StringUtils {
    var name: String = "StringUtils"
}

fun StringUtils.CustomGetLenth(): Int {
    return this.name.length
}
複製代碼
package com.boy.learning.kotlinlearningtravel.extensions
fun main(args: Array<String>) {
     //-----------------------擴展函數(其餘包下的kt文件)-------------------------------------
    val lenth = StringUtils().CustomGetLenth()
    println(lenth)//輸出結果-------------------------11-------------------------
}
複製代碼

範型化的擴展函數

class Test2 {}
//-----------------------範型化的擴展函數-------------------------------------
fun <T> Test2.temp(t: T) {
    when (t) {
        is String -> println("t is String:$t")
        is Int -> println("t is Int:$t")
        else -> println("既不是String也不是Int")

    }
}

fun main(args: Array<String>) {
    Test2().temp(1)//輸出結果-------------------------t is Int:1-------------------------
    Test2().temp("Boyi-Chen")//輸出結果-------------------------t is String:Boyi-Chen-------------------------
}
複製代碼

擴展函數不可覆蓋(overriding)

//-----------------------擴展函數不可覆蓋(overriding)-------------------------------------
open class View {}

class Button : View() {}

fun View.longClick() = println("base view longClicked")
fun Button.longClick() = println("button longClicked")

fun main(args: Array<String>) {
    //-----------------------擴展函數不可覆蓋(overriding)-------------------------------------
    val button: View = Button()
    button.longClick()//輸出結果-------------------------base view longClicked-------------------------

    val button2: Button = Button()
    button2.longClick()//輸出結果-------------------------button longClicked-------------------------
}
複製代碼

問題

1. 看到這裏是否是以爲有點奇怪,擴展函數有什麼用?java中有相似的麼?
我也是帶着這個疑問纔去找答案的。

因爲Kotlin文件在通過Kotlin編譯器編譯後會生成Java字節碼,因此我只要找到對應的字節碼文件就能夠找到答案了。 我在字節碼文件中找到了答案 StringUtils.kt 源代碼app

package com.boy.learning.kotlinlearningtravel.extensions.utils

class StringUtils {
    var name: String = "StringUtils"
}

fun StringUtils.CustomGetLenth(): Int {
    return this.name.length
}
複製代碼

StringUtilskt.class 字節碼文件jvm

package com.boy.learning.kotlinlearningtravel.extensions.utils;

import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

@Metadata(mv={1, 1, 13}, bv={1, 0, 3}, k=2, d1={"\000\f\n\000\n\002\020\b\n\002\030\002\n\000\032\n\020\000\032\0020\001*\0020\002��\006\003"}, d2={"CustomGetLenth", "", "Lcom/boy/learning/kotlinlearningtravel/extensions/utils/StringUtils;", "appKt_debug"})
public final class StringUtilsKt
{
  public static final int CustomGetLenth(@NotNull StringUtils $receiver)
  {
    Intrinsics.checkParameterIsNotNull($receiver, "receiver$0");return $receiver.getName().length();
  }
}
複製代碼

其實如今能夠看出來了,擴展函數通過kt編譯器編譯後,生成 public static final 的靜態方法,就是java中的xxxUtils工具類。這樣使得Kotlin比java更方便使用,效率更高。函數

2. kotlin擴展函數,java能夠調用麼?

java中使用kt定義的擴展函數(不要問我爲何,反正字節碼中聲明的靜態函數就是這樣的,拿起鍵盤就是幹)工具

public class MainTest {
    public static void main(String[] args) {
        int lenth = StringUtilsKt.CustomGetLenth(new StringUtils());
        System.out.println(lenth);//11
    }
}
複製代碼

認真看的同窗可能會看到靜態函數須要傳(@NotNull StringUtils $receiver),這裏的receiver是接收者實例化對象,文章開頭擴展函數就給你們解釋了,仍是截個圖,你們看着方便點。ui

源碼

請關注公衆號並在後臺回覆:kotlinthis

Kotlin重構系列分享教程

Kotlin環境搭建

Kotlin重構初體驗之告別FindViewById

Kotlin基本類型

Kotlin 控制語句 if when for while

Kotlin返回與跳轉

Kotlin 類和對象

Kotlin繼承

Kotlin接口

Kotlin重構如何兼容原先的ButterKnife、EventBus3.1

當ButterKnife8.8.1碰到AndroidX怎麼辦

Githup教程開源項目

Python爬蟲系列分享教程

Python爬蟲之旅之Selenium庫的使用

Python爬蟲之旅之豆瓣音樂

請關注我(分享平常開發)

參考文章 gad.qq.com/article/det…

相關文章
相關標籤/搜索