栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Java lambda函数将如何编译?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java lambda函数将如何编译?

VM决定如何实现lambda,而不是编译器。

请参阅《 Lambda表达式的翻译》中的

Translation strategy
部分。

我们没有生成字节码来创建实现lambda表达式的对象(例如,调用内部类的构造函数),而是描述了构造lambda的方法,并将实际构造委托给语言运行时。该配方被编码在invokedynamic指令的静态和动态参数列表中。

for
就简单的编译或性能而言,从你的示例中进行构造是最有效的方法(但根据测试,性能差异很小)。

插件:

我创建并分解了两个示例:

for (String string: Arrays.asList("hello")) {    System.out.println(string);}

反汇编的字节码,常量和其他信息:

Classfile LambdaCode.class  Last modified 30.05.2013; size 771 bytes  MD5 checksum 79bf2821b5a14485934e5cebb60c99d6  Compiled from "LambdaCode.java"public class test.lambda.LambdaCode  SourceFile: "LambdaCode.java"  minor version: 0  major version: 52  flags: ACC_PUBLIC, ACC_SUPERConstant pool:   #1 = Methodref          #11.#22        //  java/lang/Object."<init>":()V   #2 = Class   #23 //  java/lang/String   #3 = String  #24 //  hello   #4 = Methodref          #25.#26        //  java/util/Arrays.asList:([Ljava/lang/Object;)Ljava/util/List;   #5 = InterfaceMethodref #27.#28        //  java/util/List.iterator:()Ljava/util/Iterator;   #6 = InterfaceMethodref #29.#30        //  java/util/Iterator.hasNext:()Z   #7 = InterfaceMethodref #29.#31        //  java/util/Iterator.next:()Ljava/lang/Object;   #8 = Fieldref#32.#33        //  java/lang/System.out:Ljava/io/PrintStream;   #9 = Methodref          #34.#35        //  java/io/PrintStream.println:(Ljava/lang/String;)V  #10 = Class   #36 //  test/lambda/LambdaCode  #11 = Class   #37 //  java/lang/Object  #12 = Utf8    <init>  #13 = Utf8    ()V  #14 = Utf8    Code  #15 = Utf8    LineNumberTable  #16 = Utf8    main  #17 = Utf8    ([Ljava/lang/String;)V  #18 = Utf8    StackMapTable  #19 = Class   #38 //  java/util/Iterator  #20 = Utf8    SourceFile  #21 = Utf8    LambdaCode.java  #22 = NameAndType        #12:#13        //  "<init>":()V  #23 = Utf8    java/lang/String  #24 = Utf8    hello  #25 = Class   #39 //  java/util/Arrays  #26 = NameAndType        #40:#41        //  asList:([Ljava/lang/Object;)Ljava/util/List;  #27 = Class   #42 //  java/util/List  #28 = NameAndType        #43:#44        //  iterator:()Ljava/util/Iterator;  #29 = Class   #38 //  java/util/Iterator  #30 = NameAndType        #45:#46        //  hasNext:()Z  #31 = NameAndType        #47:#48        //  next:()Ljava/lang/Object;  #32 = Class   #49 //  java/lang/System  #33 = NameAndType        #50:#51        //  out:Ljava/io/PrintStream;  #34 = Class   #52 //  java/io/PrintStream  #35 = NameAndType        #53:#54        //  println:(Ljava/lang/String;)V  #36 = Utf8    test/lambda/LambdaCode  #37 = Utf8    java/lang/Object  #38 = Utf8    java/util/Iterator  #39 = Utf8    java/util/Arrays  #40 = Utf8    asList  #41 = Utf8    ([Ljava/lang/Object;)Ljava/util/List;  #42 = Utf8    java/util/List  #43 = Utf8    iterator  #44 = Utf8    ()Ljava/util/Iterator;  #45 = Utf8    hasNext  #46 = Utf8    ()Z  #47 = Utf8    next  #48 = Utf8    ()Ljava/lang/Object;  #49 = Utf8    java/lang/System  #50 = Utf8    out  #51 = Utf8    Ljava/io/PrintStream;  #52 = Utf8    java/io/PrintStream  #53 = Utf8    println  #54 = Utf8    (Ljava/lang/String;)V{  public test.lambda.LambdaCode();    descriptor: ()V    flags: ACC_PUBLIC    Code:      stack=1, locals=1, args_size=1         0: aload_0     1: invokespecial #1       // Method java/lang/Object."<init>":()V         4: return   LineNumberTable:        line 15: 0  public static void main(java.lang.String[]);    descriptor: ([Ljava/lang/String;)V    flags: ACC_PUBLIC, ACC_STATIC    Code:      stack=4, locals=3, args_size=1         0: iconst_1    1: anewarray     #2       // class java/lang/String         4: dup         5: iconst_0    6: ldc#3       // String hello         8: aastore     9: invokestatic  #4       // Method java/util/Arrays.asList:([Ljava/lang/Object;)Ljava/util/List;        12: invokeinterface #5,  1 // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;        17: astore_1   18: aload_1    19: invokeinterface #6,  1 // InterfaceMethod java/util/Iterator.hasNext:()Z        24: ifeq          47        27: aload_1    28: invokeinterface #7,  1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;        33: checkcast     #2       // class java/lang/String        36: astore_2   37: getstatic     #8       // Field java/lang/System.out:Ljava/io/PrintStream;        40: aload_2    41: invokevirtual #9       // Method java/io/PrintStream.println:(Ljava/lang/String;)V        44: goto          18        47: return   LineNumberTable:        line 35: 0        line 36: 37        line 37: 44        line 38: 47      StackMapTable: number_of_entries = 2frame_type = 252   offset_delta = 18        locals = [ class java/util/Iterator ]frame_type = 250           offset_delta = 28}

Arrays.asList("hello").forEach(p -> {System.out.println(p);});

反汇编的字节码,常量和其他信息:

Classfile LambdaCode.class  Last modified 30.05.2013; size 1262 bytes  MD5 checksum 4804e0a37b73141d5791cc39d51d649c  Compiled from "LambdaCode.java"public class test.lambda.LambdaCode  SourceFile: "LambdaCode.java"  InnerClasses:       public static final #64= #63 of #70; //Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles  BootstrapMethods:    0: #27 invokestatic java/lang/invoke/Lambdametafactory.metaFactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;      Method arguments:        #28 invokeinterface java/util/function/Consumer.accept:(Ljava/lang/Object;)V        #29 invokestatic test/lambda/LambdaCode.lambda$0:(Ljava/lang/String;)V        #30 (Ljava/lang/String;)V  minor version: 0  major version: 52  flags: ACC_PUBLIC, ACC_SUPERConstant pool:   #1 = Methodref          #10.#21        //  java/lang/Object."<init>":()V   #2 = Class   #22 //  java/lang/String   #3 = String  #23 //  hello   #4 = Methodref          #24.#25        //  java/util/Arrays.asList:([Ljava/lang/Object;)Ljava/util/List;   #5 = InvokeDynamic      #0:#31         //  #0:lambda$:()Ljava/util/function/Consumer;   #6 = InterfaceMethodref #32.#33        //  java/util/List.forEach:(Ljava/util/function/Consumer;)V   #7 = Fieldref#34.#35        //  java/lang/System.out:Ljava/io/PrintStream;   #8 = Methodref          #36.#37        //  java/io/PrintStream.println:(Ljava/lang/String;)V   #9 = Class   #38 //  test/lambda/LambdaCode  #10 = Class   #39 //  java/lang/Object  #11 = Utf8    <init>  #12 = Utf8    ()V  #13 = Utf8    Code  #14 = Utf8    LineNumberTable  #15 = Utf8    main  #16 = Utf8    ([Ljava/lang/String;)V  #17 = Utf8    lambda$0  #18 = Utf8    (Ljava/lang/String;)V  #19 = Utf8    SourceFile  #20 = Utf8    LambdaCode.java  #21 = NameAndType        #11:#12        //  "<init>":()V  #22 = Utf8    java/lang/String  #23 = Utf8    hello  #24 = Class   #40 //  java/util/Arrays  #25 = NameAndType        #41:#42        //  asList:([Ljava/lang/Object;)Ljava/util/List;  #26 = Utf8    BootstrapMethods  #27 = MethodHandle       #6:#43         //  invokestatic java/lang/invoke/Lambdametafactory.metaFactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;  #28 = MethodHandle       #9:#44         //  invokeinterface java/util/function/Consumer.accept:(Ljava/lang/Object;)V  #29 = MethodHandle       #6:#45         //  invokestatic test/lambda/LambdaCode.lambda$0:(Ljava/lang/String;)V  #30 = MethodType         #18 //  (Ljava/lang/String;)V  #31 = NameAndType        #46:#47        //  lambda$:()Ljava/util/function/Consumer;  #32 = Class   #48 //  java/util/List  #33 = NameAndType        #49:#50        //  forEach:(Ljava/util/function/Consumer;)V  #34 = Class   #51 //  java/lang/System  #35 = NameAndType        #52:#53        //  out:Ljava/io/PrintStream;  #36 = Class   #54 //  java/io/PrintStream  #37 = NameAndType        #55:#18        //  println:(Ljava/lang/String;)V  #38 = Utf8    test/lambda/LambdaCode  #39 = Utf8    java/lang/Object  #40 = Utf8    java/util/Arrays  #41 = Utf8    asList  #42 = Utf8    ([Ljava/lang/Object;)Ljava/util/List;  #43 = Methodref          #56.#57        //  java/lang/invoke/Lambdametafactory.metaFactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;  #44 = InterfaceMethodref #58.#59        //  java/util/function/Consumer.accept:(Ljava/lang/Object;)V  #45 = Methodref          #9.#60         //  test/lambda/LambdaCode.lambda$0:(Ljava/lang/String;)V  #46 = Utf8    lambda$  #47 = Utf8    ()Ljava/util/function/Consumer;  #48 = Utf8    java/util/List  #49 = Utf8    forEach  #50 = Utf8    (Ljava/util/function/Consumer;)V  #51 = Utf8    java/lang/System  #52 = Utf8    out  #53 = Utf8    Ljava/io/PrintStream;  #54 = Utf8    java/io/PrintStream  #55 = Utf8    println  #56 = Class   #61 //  java/lang/invoke/Lambdametafactory  #57 = NameAndType        #62:#66        //  metaFactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;  #58 = Class   #67 //  java/util/function/Consumer  #59 = NameAndType        #68:#69        //  accept:(Ljava/lang/Object;)V  #60 = NameAndType        #17:#18        //  lambda$0:(Ljava/lang/String;)V  #61 = Utf8    java/lang/invoke/Lambdametafactory  #62 = Utf8    metaFactory  #63 = Class   #71 //  java/lang/invoke/MethodHandles$Lookup  #64 = Utf8    Lookup  #65 = Utf8    InnerClasses  #66 = Utf8    (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;  #67 = Utf8    java/util/function/Consumer  #68 = Utf8    accept  #69 = Utf8    (Ljava/lang/Object;)V  #70 = Class   #72 //  java/lang/invoke/MethodHandles  #71 = Utf8    java/lang/invoke/MethodHandles$Lookup  #72 = Utf8    java/lang/invoke/MethodHandles{  public test.lambda.LambdaCode();    descriptor: ()V    flags: ACC_PUBLIC    Code:      stack=1, locals=1, args_size=1         0: aload_0     1: invokespecial #1       // Method java/lang/Object."<init>":()V         4: return   LineNumberTable:        line 15: 0  public static void main(java.lang.String[]);    descriptor: ([Ljava/lang/String;)V    flags: ACC_PUBLIC, ACC_STATIC    Code:      stack=4, locals=1, args_size=1         0: iconst_1    1: anewarray     #2       // class java/lang/String         4: dup         5: iconst_0    6: ldc#3       // String hello         8: aastore     9: invokestatic  #4       // Method java/util/Arrays.asList:([Ljava/lang/Object;)Ljava/util/List;        12: invokedynamic #5,  0   // InvokeDynamic #0:lambda$:()Ljava/util/function/Consumer;        17: invokeinterface #6,  2 // InterfaceMethod java/util/List.forEach:(Ljava/util/function/Consumer;)V        22: return   LineNumberTable:        line 28: 0        line 38: 22}

对于Lambda示例,编译器生成的类文件更复杂且更大(771b对1262b)。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/596766.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号