欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一篇文章弄懂kotlin的擴(kuò)展方法

 更新時(shí)間:2019年09月09日 08:37:38   作者:DROID  
這篇文章主要給大家介紹了如何通過一篇文章弄懂kotlin的擴(kuò)展方法,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用kotlin具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧

Usage

擴(kuò)展函數(shù)是 kotlin 的又一殺手锏功能,能夠在不修改源碼的基礎(chǔ)上,擴(kuò)展某些類的能力,方便開發(fā)。

例如這里演示了給 String 添加一個(gè)獲取第一個(gè)元素的方法。

fun String.first(): Char {
  if (isEmpty()) {
    throw NoSuchElementException("String is empty")
  }
  return this[0]
}

fun main(args: Array<String>) {
  println("Hello,World".first())
}

這里需要額外注意的地方在于擴(kuò)展函數(shù)的方法體中,是能夠直接訪問擴(kuò)展對象 public 的變量的。例如上面的方法里面,我們也可以這么寫:

fun String.first(): Char {
  if (length < 1) {
    throw NoSuchElementException("String is empty")
  }
  return this[0]
}

通過 this 可以在方法內(nèi),訪問擴(kuò)展對象,這里就是通過 this[0] 拿到第一個(gè)字符的。

Under in hood

看上去很厲害哈,但他的原理卻非常簡單。我們要時(shí)刻記住,kotlin JVM 是基于 JVM 開發(fā)的,kotlin 源碼最后會(huì)變成字節(jié)碼而后被運(yùn)行。當(dāng)遇到語法上不太懂的地方,直接反編譯字節(jié)碼,或者 Decompile 成 Java 方法,就能洞察里面的玄機(jī)。

我們將上述代碼,Decompile 成 Java 后,就能發(fā)現(xiàn)里面的秘密。

public static final char first(@NotNull String $this$first){
  Intrinsics.checkParameterIsNotNull($this$first, "$this$first");
  if ($this$first.length() < 1) {
   throw (Throwable)(new NoSuchElementException("String is empty"));
  } else {
   return $this$first.charAt(0);
  }
}

原來是生成了一個(gè) public static final 的方法呀,不過這個(gè)生成是 kotlin 提供的語法糖,幫我們完成的??吹竭@個(gè)代碼,也解釋了為什么在擴(kuò)展對象方法內(nèi)部,能夠訪問到擴(kuò)展對象的 public 成員。

重載與多態(tài)

擴(kuò)展方法能否被繼承呢,或者重載呢?我們來看看例子

open class Animal
class Dog : Animal()

fun Animal.desc() = "Animal"
fun Dog.desc() = "Dog"

fun main(args: Array<String>) {
  println(Dog().desc())
  var animal: Animal = Dog()
  println(animal.desc())
}

// output:
// Dog
// Animal

如果擴(kuò)展方法能夠被重載,那么兩次都應(yīng)該輸出 Dog,我們還是和前面方法一樣,來看看真相。

@NotNull
public static final String desc(@NotNull Animal $this$desc) {
  Intrinsics.checkParameterIsNotNull($this$desc, "$this$desc");
  return "Animal";
}

@NotNull
public static final String desc(@NotNull Dog $this$desc) {
  Intrinsics.checkParameterIsNotNull($this$desc, "$this$desc");
  return "Dog";
}

可以看到實(shí)際生成了兩個(gè) desc 方法,里面的參數(shù)不動(dòng),所以這個(gè)方法的調(diào)用,只與擴(kuò)展對象本身有關(guān)系,在編譯時(shí)已經(jīng)確定,不存在多態(tài)。

擴(kuò)展屬性

這是一個(gè)很神奇的設(shè)定,kotlin 并不能真的給擴(kuò)展對象添加一個(gè)屬性,而只是提供了一個(gè)語法糖,什么意思呢?我們具體看看下面這個(gè)例子。

var String.first: Char
  get() {
    if (isEmpty()) {
      throw NoSuchElementException(“String is empty”)
    }
    return this[0]
  }
  set(value) {
    println(“set value to $value”)
  }

fun main() {
  “Hello, World”.first = ‘G'
  println(“Hello,World”.first)
}

我們擴(kuò)展了 kotlin 的屬性,添加了一個(gè) first。我們可以分別給這個(gè)所謂的 first 屬性,注意是所謂的,添加 get 和 set 方法。然后我們可以通過 = 和 . 來調(diào)用 set 和 get 方法,就像 main 方法中那樣。但實(shí)際上,最后并沒有生成 first 屬性,我們來看看反編譯過后的代碼。

public static final Char getFirst(@NotNull String $this$first) {
  Intrinsics.checkParameterIsNotNull($this$first, "$this$first");
  CharSequence var1 = (CharSequence)$this$first;
  boolean var2 = false;
  if (var1.length() == 0) {
   throw (Throwable)(new NoSuchElementException("String is empty"));
  } else {
   return $this$first.charAt(0);
  }
}

public static final void setFirst(@NotNull String $this$first, char value) {
  Intrinsics.checkParameterIsNotNull($this$first, "$this$first");
  String var2 = "set value to " + value;
  boolean var3 = false;
  System.out.println(var2);
}

看到?jīng)]有,實(shí)際上只是添加了 setFirst 和 getFirst 兩個(gè)方法,并沒有實(shí)際的屬性添加上去。這也是 kotlin 提供給我們的語法糖之一,糖要吃,但也要小心蛀牙哦!

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對腳本之家的支持。

相關(guān)文章

  • Android so庫的熱更新問題

    Android so庫的熱更新問題

    這篇文章主要介紹了Android so庫的熱更新問題的相關(guān)資料,需要的朋友可以參考下
    2017-11-11
  • 一篇文章弄懂kotlin的擴(kuò)展方法

    一篇文章弄懂kotlin的擴(kuò)展方法

    這篇文章主要給大家介紹了如何通過一篇文章弄懂kotlin的擴(kuò)展方法,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用kotlin具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Android熱修復(fù)Tinker接入及源碼解讀

    Android熱修復(fù)Tinker接入及源碼解讀

    熱修復(fù)這項(xiàng)技術(shù),基本上已經(jīng)成為項(xiàng)目比較重要的模塊了。主要因?yàn)轫?xiàng)目在上線之后,都難免會(huì)有各種問題本文講述了Android熱修復(fù)Tinker接入及源碼解讀
    2018-09-09
  • Android應(yīng)用開發(fā):電話監(jiān)聽和錄音代碼示例

    Android應(yīng)用開發(fā):電話監(jiān)聽和錄音代碼示例

    這篇文章主要介紹了Android應(yīng)用開發(fā)中電話監(jiān)聽和電話錄音的代碼實(shí)例,同時(shí)附錄了一個(gè)拍照、錄像的例子,需要的朋友可以參考下
    2014-04-04
  • Android拼圖游戲 玩轉(zhuǎn)從基礎(chǔ)到應(yīng)用手勢變化

    Android拼圖游戲 玩轉(zhuǎn)從基礎(chǔ)到應(yīng)用手勢變化

    這篇文章主要介紹了Android拼圖游戲的實(shí)現(xiàn)方法,教大家玩轉(zhuǎn)從基礎(chǔ)到應(yīng)用手勢變化,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Android ReboundScrollView仿IOS拖拽回彈效果

    Android ReboundScrollView仿IOS拖拽回彈效果

    這篇文章主要為大家詳細(xì)介紹了Android ReboundScrollView仿IOS拖拽回彈效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • android自定義view之實(shí)現(xiàn)日歷界面實(shí)例

    android自定義view之實(shí)現(xiàn)日歷界面實(shí)例

    本篇文章主要介紹了android自定義view之實(shí)現(xiàn)日歷界面實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-03-03
  • 實(shí)例講解建立Android項(xiàng)目

    實(shí)例講解建立Android項(xiàng)目

    在本篇內(nèi)容中我們給大家整理了關(guān)于建立Android項(xiàng)目的步驟和相關(guān)知識點(diǎn),有興趣的讀者們學(xué)習(xí)下。
    2019-03-03
  • android studio3.0以上如何通過navicat訪問SQLite數(shù)據(jù)庫文件

    android studio3.0以上如何通過navicat訪問SQLite數(shù)據(jù)庫文件

    這篇文章主要介紹了android studio3.0以上如何通過navicat訪問SQLite數(shù)據(jù)庫文件,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Android EditText長按菜單中分享功能的隱藏方法

    Android EditText長按菜單中分享功能的隱藏方法

    Android EditText控件是經(jīng)常使用的控件,下面這篇文章主要給大家介紹了關(guān)于Android中EditText長按菜單中分享功能的隱藏方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02

最新評論