kotlin lambda表達(dá)式

先來看一個(gè)概念哪工。

函數(shù)式接口:函數(shù)式接口(Functional Interface)就是一個(gè)有且僅有一個(gè)抽象方法弧哎,但是可以有多個(gè)非抽象方法的接口。

比如java中的Runnable接口就是函數(shù)式接口撤嫩。

public interface Runnable {
    public abstract void run();
}

在項(xiàng)目代碼轉(zhuǎn)為使用kotlin時(shí),會(huì)存在和java代碼互相調(diào)用的問題鸭限。不知道大家有沒有注意到一個(gè)細(xì)節(jié),kotlin構(gòu)建java中的函數(shù)式接口時(shí)败京,可以轉(zhuǎn)為lambda方式。

java方式:
Runnable runnable = new Runnable() {
    @Override
    public void run() {
    }
};
val runnable = Runnable { 
    print("runnable")
}

可以看到使用lambda表達(dá)式后朴皆,對(duì)函數(shù)式接口來講泛粹,實(shí)現(xiàn)方式更加簡潔。

我們都知道kotlin代碼最終還是會(huì)被編譯為字節(jié)碼晶姊,那么kotlin中是如何實(shí)現(xiàn)lambda表達(dá)式的呢?

這得分兩種情況:

情況1: lambda表達(dá)式內(nèi)部沒有持有外部的非靜態(tài)變量钾怔,方法蒙挑。
class Lambda{
    private var name = "小明" // 外部變量
    private fun testLambda(){
        var age = 10 // 外部變量
        val runnable = Runnable { 
            print("沒有調(diào)用外部變量或方法") // 沒有調(diào)用age或者name變量
        }
    }
}

查看testLambda方法編譯后的字節(jié)碼

// 獲取靜態(tài)變量 INSTANCE(該INSTANCE實(shí)際是Runnable對(duì)象的一個(gè)實(shí)現(xiàn))
GETSTATIC Lambda$testLambda1$runnable$1.INSTANCE : LLambda$testLambda1$runnable$1;
// 檢查 INSTANCE 是否可以轉(zhuǎn)變?yōu)镽unnbale對(duì)象,否則拋出異常
CHECKCAST java/lang/Runnable
// INSTANCE推入操作數(shù)棧
ASTORE 1

翻譯成java代碼就會(huì)類似于這樣:

public class Lambda {
    private String name = "小明";

    private static Object INSTANCE = new Runnable() {
        @Override
        public void run() {
            System.out.println("沒有調(diào)用外部類的成員變量");
        }
    };

    private void testLambda1() {
        Runnable runnable = (Runnable)INSTANCE;
    }
}
可以看到這種情況下lambda表達(dá)式實(shí)際上被轉(zhuǎn)換為靜態(tài)成員變量矾利。
情況二:lambda表達(dá)式內(nèi)部持有外部的非靜態(tài)變量馋袜,方法。
class Lambda {
    private var name = "小明"
    private fun testLambda2() {
        val runnable = Runnable {
            print(name)
        }
    }
}

反編譯為java代碼:

 private final void testLambda2() {
      Runnable runnable = (Runnable)(new Runnable() {
         public final void run() {
            String var1 = Lambda.this.name;
            System.out.print(var1);
         }
      });
   }
可以看到lambda表達(dá)式是采用匿名內(nèi)部類的方式來實(shí)現(xiàn)的剑肯。

那么以上兩種方式有什么不同呢观堂?

我們都知道java中匿名內(nèi)部類都會(huì)隱式持有外部類的引用(即使不需要引用外部類的變量)让网,當(dāng)匿名內(nèi)部類中有耗時(shí)操作時(shí)师痕,容易造成內(nèi)存泄露。

像kotlin這樣的實(shí)現(xiàn)因篇,在情況一的時(shí)候,lambda內(nèi)部沒有持有外部類的引用竞滓,不會(huì)有任何內(nèi)存泄露的風(fēng)險(xiǎn)。

以上就是kotlin調(diào)用java時(shí)锯茄,lambda的實(shí)現(xiàn)方式茶没。

kotlin中Functions.kt中定義了從Function0Function22一共23個(gè)接口,每個(gè)接口有且僅有一個(gè)invoke方法抓半,F(xiàn)unction后邊的數(shù)字代表invoke方法有幾個(gè)入?yún)ⅲ?dāng)kotlin中自定義的lambda表達(dá)式在編譯的時(shí)候笛求,會(huì)被替換為對(duì)應(yīng)的接口實(shí)現(xiàn)。

比如:

val lambda: (() -> Unit) = {
}

由于沒有參數(shù)画机,所以實(shí)際上會(huì)被編譯為

Function0 lambda = new Function0{
    public void invoke(){
    }
}

當(dāng)然了新症,編譯規(guī)則也會(huì)像調(diào)用java中的函數(shù)式接口時(shí)一樣响禽,僅當(dāng)需要持有this對(duì)象時(shí)才會(huì)編譯為匿名內(nèi)部類。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末隆嗅,一起剝皮案震驚了整個(gè)濱河市侯繁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌贮竟,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件技健,死亡現(xiàn)場離奇詭異惰拱,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門馋没,熙熙樓的掌柜王于貴愁眉苦臉地迎上來降传,“玉大人,你說我怎么就攤上這事搬瑰。” “怎么了艾少?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵翼悴,是天一觀的道長。 經(jīng)常有香客問我鹦赎,道長,這世上最難降的妖魔是什么雏吭? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任陪踩,我火速辦了婚禮,結(jié)果婚禮上肩狂,老公的妹妹穿的比我還像新娘。我一直安慰自己孝治,他們只是感情好审磁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著力图,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瓤介。 梳的紋絲不亂的頭發(fā)上吕喘,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天氯质,我揣著相機(jī)與錄音祠斧,去河邊找鬼闻察。 笑死琢锋,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的钉嘹。 我是一名探鬼主播鲸阻,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼鸟悴!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起沛贪,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤揍堰,失蹤者是張志新(化名)和其女友劉穎嗅义,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體之碗,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年幽纷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了博敬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡收恢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出伦意,到底是詐尸還是另有隱情,我是刑警寧澤驮肉,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布离钝,位于F島的核電站票编,受9級(jí)特大地震影響卵渴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吊趾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一瑟啃、第九天 我趴在偏房一處隱蔽的房頂上張望论泛。 院中可真熱鬧蛹屿,春花似錦、人聲如沸错负。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽识颊。三九已至,卻和暖如春祥款,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抠艾。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國打工桨昙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留首懈,地道東北人谨敛。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像脸狸,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子炊甲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 目錄 一卿啡、Lambda介紹 在上面已經(jīng)提到了在Java中已經(jīng)被廣泛的運(yùn)用,但是也是在Java8的時(shí)候才支持這種La...
    寶馬奔馳_xyz閱讀 1,985評(píng)論 0 0
  • 基本語法 如果 lambda 表達(dá)式是函數(shù)調(diào)用的最后一個(gè)實(shí)參剑逃,它可以放到括號(hào)的外邊。 當(dāng) lambda 是函數(shù)唯一...
    蔣揚(yáng)海閱讀 478評(píng)論 0 1
  • 寫在開頭:本人打算開始寫一個(gè)Kotlin系列的教程蛹磺,一是使自己記憶和理解的更加深刻同仆,二是可以分享給同樣想學(xué)習(xí)Kot...
    胡奚冰閱讀 1,245評(píng)論 0 6
  • 1.Lambda表達(dá)式 2.Lambda語法 itit并不是kotlin的一個(gè)關(guān)鍵字2.it是在當(dāng)一個(gè)高階函數(shù)中L...
    Guow110閱讀 440評(píng)論 0 0
  • 前段時(shí)間一直在看lambda表達(dá)式俗批,但是總感覺吃不透,在深入了解lambda表達(dá)式的時(shí)候岁忘,需要很多基礎(chǔ)的知識(shí)棧。這...
    西瓜真好吃丶閱讀 2,723評(píng)論 0 7