最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java將Lambda表達式對應(yīng)的類保存到class文件中的方法示例

 更新時間:2026年05月19日 08:32:07   作者:金銀銅鐵  
大家在日常開發(fā)中應(yīng)該都用過 Lambda表達式,以下面的 java代碼為例,我們在運行 HelloWorld中的 main方法時,可以看到 r的類型信息,但是在編譯時、運行時都沒有看到 r對應(yīng)的類的 class文件,本文給大家介紹了Java將Lambda表達式對應(yīng)的類保存到class文件中的方法示例

背景

大家在日常開發(fā)中應(yīng)該都用過 Lambda表達式。以下面的 java代碼為例,我們在運行 HelloWorld中的 main方法時,可以看到 r的類型信息,但是在編譯時、運行時都沒有看到 r對應(yīng)的類的 class文件,有沒有辦法將 r對應(yīng)的類保存到 class文件里呢?本文會對此進行探討。

public class HelloWorld {
    public static void main(String[] args) {
        Runnable r = () -> System.out.println("Hello World");
        r.run();
        System.out.println("class name of r: " + r.getClass().getName());	
    }
}

要點

運行 java命令時,使用以下兩個選項中的任何一個,都可以把 Lambda表達式對應(yīng)的類自動保存到 class 文件中

  • -Djdk.invoke.LambdaMetafactory.dumpProxyClassFiles
  • -Djdk.invoke.LambdaMetafactory.dumpProxyClassFiles=true

正文

javac版本和java版本

查看javac版本

使用如下命令可以查看 javac命令的版本

javac -version

該命令在我電腦上的運行結(jié)果如下

javac 21

查看java版本

使用如下命令可以查看 java命令的版本

java -version

該命令在我電腦上的運行結(jié)果如下

openjdk version "21" 2023-09-19
OpenJDK Runtime Environment (build 21+35-2513)
OpenJDK 64-Bit Server VM (build 21+35-2513, mixed mode, sharing)

代碼

請將如下代碼保存為 HelloWorld.java ??

public class HelloWorld {
    public static void main(String[] args) {
        Runnable r = () -> System.out.println("Hello World");
        r.run();
        System.out.println("class name of r: " + r.getClass().getName());	
    }
}

編譯

使用如下的命令可以編譯 HelloWorld.java\

javac -parameters HelloWorld.java

編譯之后,執(zhí)行 tree . 命令,會看到這樣的結(jié)果 ?? (當(dāng)前目錄多了 HelloWorld.class 文件)

.
├── HelloWorld.class
└── HelloWorld.java

1 directory, 2 files

運行

使用如下的命令可以編譯 HelloWorld中的 main方法 ??

java HelloWorld

在我電腦上,該命令的運行結(jié)果如下 ?? (在您的電腦上,最后一行輸出的類名可能是其他內(nèi)容)

Hello World
class name of r: HelloWorld$$Lambda/0x000000d001000a00

看來 r的精確類型(為了便于描述,我們把它簡稱為 L吧)是一個很特殊的類(至少命名很特殊??)。在運行完 HelloWorld中的 main方法之后,當(dāng)前目錄并沒有新的文件生成。如果我們想看看 L的內(nèi)容,一個思路是讓 java虛擬機把 L保存到 class文件里(我們可以用 javap命令來查看 class文件的內(nèi)容)。

在 InnerClassLambdaMetafactory.java 里可以找到如下的選項 ??

看起來只要加上以下兩個選項的任何一個,就可以將 r對應(yīng)的類保存到 class文件里

  • -Djdk.invoke.LambdaMetafactory.dumpProxyClassFiles
  • -Djdk.invoke.LambdaMetafactory.dumpProxyClassFiles=true

我們就用第一種方法吧,完整的命令如下 ??

java -Djdk.invoke.LambdaMetafactory.dumpProxyClassFiles HelloWorld

運行完這個命令后,再運行 tree . 命令,會得到以下結(jié)果 ?? (在您的電腦上,所看到的 class\text{class}class 文件的名稱可能會有差異)

.
├── DUMP_LAMBDA_PROXY_CLASS_FILES
│   └── HelloWorld$$Lambda.0x000000f801000a00.class
├── HelloWorld.class
└── HelloWorld.java
2 directories, 3 files

當(dāng)前目錄多了一個名為 DUMP_LAMBDA_PROXY_CLASS_FILES 的目錄,這個目錄下有一個 class文件。我們用如下的命令可以查看這個 class文件的內(nèi)容

javap -v -p DUMP_LAMBDA_PROXY_CLASS_FILES/*class

我電腦上的運行結(jié)果如下 ?? (這里略去了結(jié)果中的前三行)

final class HelloWorld$$Lambda implements java.lang.Runnable
  minor version: 0
  major version: 65
  flags: (0x1030) ACC_FINAL, ACC_SUPER, ACC_SYNTHETIC
  this_class: #2                          // HelloWorld$$Lambda
  super_class: #4                         // java/lang/Object
  interfaces: 1, fields: 0, methods: 2, attributes: 0
Constant pool:
   #1 = Utf8               HelloWorld$$Lambda
   #2 = Class              #1             // HelloWorld$$Lambda
   #3 = Utf8               java/lang/Object
   #4 = Class              #3             // java/lang/Object
   #5 = Utf8               java/lang/Runnable
   #6 = Class              #5             // java/lang/Runnable
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = NameAndType        #7:#8          // "<init>":()V
  #10 = Methodref          #4.#9          // java/lang/Object."<init>":()V
  #11 = Utf8               run
  #12 = Utf8               HelloWorld
  #13 = Class              #12            // HelloWorld
  #14 = Utf8               lambda$main$0
  #15 = NameAndType        #14:#8         // lambda$main$0:()V
  #16 = Methodref          #13.#15        // HelloWorld.lambda$main$0:()V
  #17 = Utf8               Code
{
  private HelloWorld$$Lambda();
    descriptor: ()V
    flags: (0x0002) ACC_PRIVATE
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #10                 // Method java/lang/Object."<init>":()V
         4: return

  public void run();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=0, locals=1, args_size=1
         0: invokestatic  #16                 // Method HelloWorld.lambda$main$0:()V
         3: return
}

由于它的內(nèi)容并不多,我們可以嘗試手動反編譯它,反編譯的結(jié)果如下 ??

// 以下內(nèi)容是我手動反編譯的結(jié)果,不保證完全準(zhǔn)確,僅供參考

final class HelloWorld$$Lambda implements java.lang.Runnable {
  private HelloWorld$$Lambda() {
    super();
  }

  public void run() {
      HelloWorld.lambda$main$0();
  }
}

可以看到 run() 方法里會調(diào)用 HelloWorld 中的靜態(tài)方法 lambda$main$0。但是我們在 Hello.java中并沒有定義這樣的靜態(tài)方法,那我們順便把 HelloWorld.class的內(nèi)容也看一下吧 ?? (使用如下的命令就可以查看 HelloWorld.class文件的詳細(xì)內(nèi)容)

javap -v -p HelloWorld

完整的結(jié)果有點長,這里就不展示了。我手動對 HelloWorld.class\text{HelloWorld.class}HelloWorld.class 的內(nèi)容進行了反編譯,結(jié)果如下 ??

// 以下內(nèi)容是我手動反編譯的結(jié)果,不保證完全準(zhǔn)確,僅供參考

public class HelloWorld {
  public HelloWorld() {
    super();
  }
  
  public static void main(String[] arg) {
    // 這里涉及一些特殊字節(jié)碼指令,有點復(fù)雜,所以略去具體的內(nèi)容
  }
  
  // 這是一個合成方法,原始的 java 代碼中沒有它
  private static void lambda$main$0() {
    System.out.println("Hello World");
  }
}

簡要的類圖如下 ??

其他

繪制“簡要的類圖”所用到的代碼

我用了 IntelliJ IDEA 中的 PlantUML 插件來畫那張圖,完整的代碼如下 ??

@startuml
'https://plantuml.com/component-diagram

title 簡要的類圖
caption \n\n
' caption 的內(nèi)容是為了防止掘金平臺生成的水印遮蓋圖中的文字

class HelloWorld {
  + HelloWorld()
  + {static} void main(String[] arg)
  - {static} void lambda$main$0()
}

interface java.lang.Runnable
class HelloWorld$$Lambda
java.lang.Runnable <|.. HelloWorld$$Lambda

interface java.lang.Runnable {
    void run()
}

class HelloWorld$$Lambda {
  - HelloWorld$$Lambda()
  + void run()
}

note left of HelloWorld$$Lambda::run
<code>
public void run() {
  HelloWorld.lambda$main$0();
}
</code>
end note

note left of HelloWorld::lambda$main$0
這是一個合成方法,
可以認(rèn)為它的代碼是這樣的 <:point_down:>
<code>
private static void lambda$main$0() {
  System.out.println("Hello World");
}
</code>
end note

@enduml

以上就是Java將Lambda表達式對應(yīng)的類保存到class文件中的方法示例的詳細(xì)內(nèi)容,更多關(guān)于Java將Lambda對應(yīng)類保存到class的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • springboot整合couchbase集群的步驟

    springboot整合couchbase集群的步驟

    couchbase是一款開源的,分布式的nosql數(shù)據(jù)庫,主要用于分布式緩存和數(shù)據(jù)存儲領(lǐng)域,本文給大家介紹springboot整合couchbase集群的步驟,感興趣的朋友一起看看吧
    2025-03-03
  • 徹底搞懂Java多線程(四)

    徹底搞懂Java多線程(四)

    這篇文章主要給大家介紹了關(guān)于Java面試題之多線程和高并發(fā)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • 淺談springBoot注解大全

    淺談springBoot注解大全

    本篇文章主要介紹了淺談springBoot注解大全,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • 淺談一下Java中集合的迭代方式

    淺談一下Java中集合的迭代方式

    這篇文章主要介紹了淺談一下Java中集合的迭代方式,可以幫助我們學(xué)習(xí),理解函數(shù)式編程,需要的朋友可以參考下
    2023-04-04
  • JVM進程緩存Caffeine的使用

    JVM進程緩存Caffeine的使用

    本文主要介紹了JVM進程緩存Caffeine的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • Java動態(tài)獲取實現(xiàn)某個接口下所有的實現(xiàn)類對象集合

    Java動態(tài)獲取實現(xiàn)某個接口下所有的實現(xiàn)類對象集合

    今天小編就為大家分享一篇關(guān)于Java動態(tài)獲取實現(xiàn)某個接口下所有的實現(xiàn)類對象集合,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • SpringBoot整合SQLite數(shù)據(jù)庫全過程

    SpringBoot整合SQLite數(shù)據(jù)庫全過程

    sqlite是一個很輕量級的數(shù)據(jù)庫,可以滿足日常sql的需求,下面這篇文章主要給大家介紹了關(guān)于SpringBoot整合SQLite數(shù)據(jù)庫的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-03-03
  • Java調(diào)用Python代碼實現(xiàn)Word轉(zhuǎn)化為PDF格式

    Java調(diào)用Python代碼實現(xiàn)Word轉(zhuǎn)化為PDF格式

    這篇文章主要為大家詳細(xì)介紹了Java如何實現(xiàn)調(diào)用Python代碼實現(xiàn)Word轉(zhuǎn)化為PDF格式,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2026-03-03
  • Spring boot JPA實現(xiàn)分頁和枚舉轉(zhuǎn)換代碼示例

    Spring boot JPA實現(xiàn)分頁和枚舉轉(zhuǎn)換代碼示例

    這篇文章主要介紹了Spring boot JPA實現(xiàn)分頁和枚舉轉(zhuǎn)換代碼示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09
  • Java數(shù)據(jù)結(jié)構(gòu)之有向圖設(shè)計與實現(xiàn)詳解

    Java數(shù)據(jù)結(jié)構(gòu)之有向圖設(shè)計與實現(xiàn)詳解

    有向圖是具有方向性的圖,由一組頂點和一組有方向的邊組成,每條方向的邊都連著一對有序的頂點。本文為大家介紹的是有向圖的設(shè)計與實現(xiàn),需要的可以參考一下
    2022-11-11

最新評論

米易县| 岳阳市| 那曲县| 日喀则市| 萨迦县| 溧水县| 永寿县| 鹿邑县| 山西省| 临泽县| 稷山县| 东阿县| 石景山区| 章丘市| 昆明市| 临颍县| 定日县| 北碚区| 鄯善县| 武威市| 曲沃县| 巢湖市| 泰顺县| 武陟县| 遵义市| 稻城县| 尼玛县| 昌邑市| 公安县| 乳山市| 格尔木市| 莎车县| 永昌县| 互助| 岫岩| 威远县| 黑龙江省| 奇台县| 江油市| 体育| 拉萨市|