JDK8引入了Lambda表達式以后,對我們寫代碼提供了很大的便利,那么Lambda表達式是如何運用簡單表示來達到運行效果的呢?今天,我們通過一個例子來學習下Lambda表達式的底層運行原理!
一、創建測試樣例
首先:我們創建一個測試類App.java,在它內部新建一個函數式接口Lam.java,只有一個抽象方法print(),作用是將傳入的消息加工后再輸出。
然后:我們在測試類App.java中進行lambda表達式的創建測試。
代碼如下:
public class App {
public static void main(String[] args) {
Lam lam = (msg) -> "log:" + msg;
String result = lam.print("Test");
System.out.println(result);
}
}
interface Lam {
String print(String msg);
}
二、利用Java命令編譯分析
首先,我們進行javac命令的編譯,會生成兩個class文件:
javac App.java
然后,我們通過javap -p命令打開Lam.class:
javap -p Lam.class
從圖中我們可以看到,因為Lam.class是App.class的內部類,所以提示我們它是App.java編譯過來的,並且其內部只有一個abstract方法print()。
接下來,我們再打開App.class:
javap -p App.class
App.class中一共有三個方法,一個默認構造方法,一個main方法,還多了一個我們沒有定義過的方法:lambda$main$0(String),很明顯,這個方法就是lambda表達式內邏輯操作方法,它是一個static的方法,入參就是我們傳入的msg類型String。
那么,這個lambda$main$0(String)方法是怎么被調用的呢?我們通過對java命令指定選項查看底層詳細的編譯過程:
java -Djdk.internal.lambda.dumpProxyClasses App
我們能夠看到多出來一個App$$Lambda$1.class文件,打開文件:
javap -p App$$Lambda$1.class
我們看到,這個類是一個實現Lam接口的final類,它內部實現了print()方法。
我們再通過javap -c查看一下它內部詳細信息:
javap -c App$$Lambda$1.class
由此我們可以看出,App$$Lambda\(1.class的print()方法執行了App.lambda\)main$0(),因此,我們就可以得出結論:
- Java在編譯時,首先,在App內將Lambda表達式抽取出來作為一個static方法lambda$main$0(String);
- 然后,對Lam.class做了默認實現App$$Lambda$1.class,並在內部print()方法中調用了App內的static方法:lambda$main$0();
- 接下來,執行App的main()方法時,就會對lambda表達式利用實現類的print()方法運行;
- 最后,將結果返回,並打印。
這就是Lambda表達式的底層運行邏輯。
三、文末
以上,就是我們通過一個實例,運用Java命令,來理解Lambda表達式的底層運行原理的全部內容,希望對你有所幫助!
O(∩_∩)O