第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Lambda 表達式 VS 匿名內(nèi)部類

本節(jié)我們將重點討論下 Lambda 表達式與匿名內(nèi)部類之間除了語法外還有哪些差別。再開始講解之前我們先列出兩者重要的兩點區(qū)別:

  • 無標識性: 內(nèi)部類會確保創(chuàng)建一個擁有唯一表示的對象,而 Lambda 表達式的計算結(jié)果有可能有唯一標識,也可能沒有。
  • 作用域規(guī)則: 由于內(nèi)部類可以從父類繼承屬性,Lambda 表達式卻不能,所以,內(nèi)部類的作用域規(guī)則比 Lambda 表達式要復雜。(關(guān)于 Lambda 表達式的作用域規(guī)則可以回看 03 節(jié)的內(nèi)容)

我們來看一個例子:

實例演示
預覽 復制
復制成功!
public class TestLambdaAndInnerClass  {
    public void test(){
        //匿名類實現(xiàn)
        Runnable innerRunnable = new Runnable(){
            @Override
            public void run() {
                System.out.println("call run in innerRunnable:\t"+this.getClass());
            }
        };
        //Lambda表達式實現(xiàn)
        Runnable lambdaRunnable = () -> System.out.println("call run in lambdaRunnable:\t"+this.getClass());
        new Thread(innerRunnable).start();
        new Thread(lambdaRunnable).start();
    }

    public static void main(String...s){
        new TestLambdaAndInnerClass().test();
    }
}

運行案例 點擊 "運行案例" 可查看在線運行效果

返回結(jié)果為:

call run in innerRunnable:  class com.github.x19990416.item.TestLambdaAndInnerClass$1  
call run in lambdaRunnable: class com.github.x19990416.item.TestLambdaAndInnerClass

上面的例子分別在內(nèi)部類和 Lambda 表達式中調(diào)用各自的 this 指針。我們發(fā)現(xiàn) Lambda 表達式的 this 指針指向的是其外圍類 TestLambdaAndInnerClass,匿名內(nèi)部類的指針指向的是其本身。(對于 super 也是一樣的結(jié)果)

我們來看下編譯出來的文件:

?
圖片描述
?

其中 TestLambdaAndInnerClass$1.class 是匿名類 innerRunnable 編譯出來的 class 文件,對于 Lambda 表達式 lambdaRunnable 則沒有編譯出具體的 class 文件。

這說明對于 Lambda 表達式而言,編譯器并不認為它是一個完全的類(或者說它是一個特殊的類對象),所以也不具備一個完全類的特征。

Tips: 匿名類的 this、super 指針指向的是其自身的實例,而 Lambda 表達式的 this、super 指針指向的是創(chuàng)建這個 Lambda 表達式的類對象的實例。

1. 無標識性問題

在 Lambda 表達式出現(xiàn)之前,一個 Java 程序的行為總是與對象關(guān)聯(lián),以標識、狀態(tài)和行為為特征。然而 Lambda 表達式則違背了這個規(guī)則。

雖然 Lambda 表達式可以共享對象的一些屬性,但是表示行為是其唯一的用處。由于沒有狀態(tài),所以表示問題也就不那么重要了。在 Java 語言的規(guī)范中對 Lambda 表達式唯一的要求就是必須計算出其實現(xiàn)的相當?shù)暮瘮?shù)接口的實例類。如果 Java 對每個 Lambda 表達式都擁有唯一的表示,那么 Java 就沒有足夠的靈活性來對系統(tǒng)進行優(yōu)化。

2. Lambda 表達式的作用域規(guī)則

匿名內(nèi)部類與大多數(shù)類一樣,由于它可以引用從父類繼承下來的名字,以及聲明在外部類中的名字,所以它的作用域規(guī)則非常復雜。

Lambda 表達式由于不會從父類型中繼承名字,所以它的作用于規(guī)則要簡單很多。除了參數(shù)以外,用在 Lambda 表達式中的名字的含義與表達式外面是一樣的。

由于 Lambda 表達式的聲明就是一個語句塊,所以 thissuper與表達式外圍環(huán)境的含義一樣,換言之它們指向的是外圍對象的父類對象。

3. 小結(jié)

本節(jié)我們主要討論了 Lambda 表達式與匿名內(nèi)部類的本質(zhì)區(qū)別,其中重要的是要記住 thissuper 在兩者之間的作用范圍。記住這個作用范圍可以更好的幫助我們理解 Lambda 表達式的作用域,避免我們在使用 Lambda 表達式中由于作用域引起的 bug,這一類的 bug 在實際中定位是非常困難的。

?

在 Java 里面,所有的方法參數(shù)都是有固定類型的,比如將數(shù)字 9 作為參數(shù)傳遞給一個方法,它的類型是 int;字符串 “9” 作為參數(shù)傳遞給方法,它的類型是 String。那么 Lambda 表達式的類型由是什么呢?通過本節(jié)我們學習什么是函數(shù)式接口,它與 Lambda 表達式的關(guān)系。