lambda表达式是否具有与之关联的对象,为什么“ this”不引用lambda表达式的对象?

时间:2018-08-13 19:56:16

标签: java lambda java-8

我对是否有与lambda表达式相关联的对象感到困惑,因为据说在lambda表达式的情况下“ this”不引用lambda表达式的对象,因为lambda表达式没有有任何对象,但又有人说,如果lambda表达式未捕获外部作用域中的变量,则每次lambda表达式的调用都将使用同一单例对象。

现在,我假设将有一个与lambda表达式关联的对象(我想这回答了我的第一个问题,如果我错了,请纠正我),所以我的问题是那就是为什么“ this”不引用lambda表达式的对象,就像匿名类的情况一样。


更新: 我的3个测试类:

import java.util.function.Consumer;

public class LambdaByteCodeAnalysis1 {

    public static void main(String[] args) {
        testConsumer();
    }

    private static void testConsumer() {
        // *** void accept(T t); ***
        testConsumerImpl((value) -> System.out.println("Hello, Mr. " + value));

    }
    private static void testConsumerImpl(Consumer<Object> consumer) {
        consumer.accept("testConsumer");
    }

}


##############
import java.util.function.Consumer;

public class LambdaByteCodeAnalysis2 {

    public static void main(String[] args) {
        testConsumer();
    }

    private static void testConsumer() {
        int testing = 0;
        testConsumerImpl((value) -> {
            System.out.println("Hello, Mr. " + value);
            System.out.println(testing);
        });

    }
    private static void testConsumerImpl(Consumer<Object> consumer) {
        consumer.accept("testConsumer");
    }

}


################
import java.util.function.Consumer;

public class LambdaByteCodeAnalysis3 {

    int testing = 0;

    public static void main(String[] args) {
        testConsumer();
    }

    private static void testConsumer() {
        LambdaByteCodeAnalysis3 lambdaByteCodeAnalysis3 = new LambdaByteCodeAnalysis3();
        testConsumerImpl((value) -> {
            System.out.println("Hello, Mr. " + value);
            System.out.println(lambdaByteCodeAnalysis3.testing);
        });

    }
    private static void testConsumerImpl(Consumer<Object> consumer) {
        consumer.accept("testConsumer");
    }

}

现在,字节码的顺序相同:

LambdaByteCodeAnalysis1.class

C:\E_Drive\Projects\SourceCode\Learning\learn\src\com\learn\oracle\LearningJavaLang\ClassesAndObject\LamdaExpression>javap -v LambdaByteCodeAnalysis1
Classfile /C:/E_Drive/Projects/SourceCode/Learning/learn/src/com/learn/oracle/LearningJavaLang/ClassesAndObject/LamdaExpression/LambdaByteCodeAnalysis1.class
  Last modified 15 Aug, 2018; size 1574 bytes
  MD5 checksum d90045ca82de96636d8fc91f54637c32
  Compiled from "LambdaByteCodeAnalysis1.java"
public class LambdaByteCodeAnalysis1
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #16.#32        // java/lang/Object."<init>":()V
   #2 = Methodref          #15.#33        // LambdaByteCodeAnalysis1.testConsumer:()V
   #3 = InvokeDynamic      #0:#38         // #0:accept:()Ljava/util/function/Consumer;
   #4 = Methodref          #15.#39        // LambdaByteCodeAnalysis1.testConsumerImpl:(Ljava/util/function/Consumer;)V
   #5 = String             #23            // testConsumer
   #6 = InterfaceMethodref #40.#41        // java/util/function/Consumer.accept:(Ljava/lang/Object;)V
   #7 = Fieldref           #42.#43        // java/lang/System.out:Ljava/io/PrintStream;
   #8 = Class              #44            // java/lang/StringBuilder
   #9 = Methodref          #8.#32         // java/lang/StringBuilder."<init>":()V
  #10 = String             #45            // Hello, Mr.
  #11 = Methodref          #8.#46         // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #12 = Methodref          #8.#47         // java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
  #13 = Methodref          #8.#48         // java/lang/StringBuilder.toString:()Ljava/lang/String;
  #14 = Methodref          #49.#50        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #15 = Class              #51            // LambdaByteCodeAnalysis1
  #16 = Class              #52            // java/lang/Object
  #17 = Utf8               <init>
  #18 = Utf8               ()V
  #19 = Utf8               Code
  #20 = Utf8               LineNumberTable
  #21 = Utf8               main
  #22 = Utf8               ([Ljava/lang/String;)V
  #23 = Utf8               testConsumer
  #24 = Utf8               testConsumerImpl
  #25 = Utf8               (Ljava/util/function/Consumer;)V
  #26 = Utf8               Signature
  #27 = Utf8               (Ljava/util/function/Consumer<Ljava/lang/Object;>;)V
  #28 = Utf8               lambda$testConsumer$0
  #29 = Utf8               (Ljava/lang/Object;)V
  #30 = Utf8               SourceFile
  #31 = Utf8               LambdaByteCodeAnalysis1.java
  #32 = NameAndType        #17:#18        // "<init>":()V
  #33 = NameAndType        #23:#18        // testConsumer:()V
  #34 = Utf8               BootstrapMethods
  #35 = MethodHandle       #6:#53         // invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/Stri
ng;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #36 = MethodType         #29            //  (Ljava/lang/Object;)V
  #37 = MethodHandle       #6:#54         // invokestatic LambdaByteCodeAnalysis1.lambda$testConsumer$0:(Ljava/lang/Object;)V
  #38 = NameAndType        #55:#56        // accept:()Ljava/util/function/Consumer;
  #39 = NameAndType        #24:#25        // testConsumerImpl:(Ljava/util/function/Consumer;)V
  #40 = Class              #57            // java/util/function/Consumer
  #41 = NameAndType        #55:#29        // accept:(Ljava/lang/Object;)V
  #42 = Class              #58            // java/lang/System
  #43 = NameAndType        #59:#60        // out:Ljava/io/PrintStream;
  #44 = Utf8               java/lang/StringBuilder
  #45 = Utf8               Hello, Mr.
  #46 = NameAndType        #61:#62        // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #47 = NameAndType        #61:#63        // append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
  #48 = NameAndType        #64:#65        // toString:()Ljava/lang/String;
  #49 = Class              #66            // java/io/PrintStream
  #50 = NameAndType        #67:#68        // println:(Ljava/lang/String;)V
  #51 = Utf8               LambdaByteCodeAnalysis1
  #52 = Utf8               java/lang/Object
  #53 = Methodref          #69.#70        // java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang
/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #54 = Methodref          #15.#71        // LambdaByteCodeAnalysis1.lambda$testConsumer$0:(Ljava/lang/Object;)V
  #55 = Utf8               accept
  #56 = Utf8               ()Ljava/util/function/Consumer;
  #57 = Utf8               java/util/function/Consumer
  #58 = Utf8               java/lang/System
  #59 = Utf8               out
  #60 = Utf8               Ljava/io/PrintStream;
  #61 = Utf8               append
  #62 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
  #63 = Utf8               (Ljava/lang/Object;)Ljava/lang/StringBuilder;
  #64 = Utf8               toString
  #65 = Utf8               ()Ljava/lang/String;
  #66 = Utf8               java/io/PrintStream
  #67 = Utf8               println
  #68 = Utf8               (Ljava/lang/String;)V
  #69 = Class              #72            // java/lang/invoke/LambdaMetafactory
  #70 = NameAndType        #73:#77        // metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invok
e/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #71 = NameAndType        #28:#29        // lambda$testConsumer$0:(Ljava/lang/Object;)V
  #72 = Utf8               java/lang/invoke/LambdaMetafactory
  #73 = Utf8               metafactory
  #74 = Class              #79            // java/lang/invoke/MethodHandles$Lookup
  #75 = Utf8               Lookup
  #76 = Utf8               InnerClasses
  #77 = Utf8               (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke
/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #78 = Class              #80            // java/lang/invoke/MethodHandles
  #79 = Utf8               java/lang/invoke/MethodHandles$Lookup
  #80 = Utf8               java/lang/invoke/MethodHandles
{
  public LambdaByteCodeAnalysis1();
    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 3: 0

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=0, locals=1, args_size=1
         0: invokestatic  #2                  // Method testConsumer:()V
         3: return
      LineNumberTable:
        line 6: 0
        line 7: 3
}
SourceFile: "LambdaByteCodeAnalysis1.java"
InnerClasses:
     public static final #75= #74 of #78; //Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
BootstrapMethods:
  0: #35 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljav
a/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #36 (Ljava/lang/Object;)V
      #37 invokestatic LambdaByteCodeAnalysis1.lambda$testConsumer$0:(Ljava/lang/Object;)V
      #36 (Ljava/lang/Object;)V

C:\E_Drive\Projects\SourceCode\Learning\learn\src\com\learn\oracle\LearningJavaLang\ClassesAndObject\LamdaExpression>

LambdaByteCodeAnalysis2.class

C:\E_Drive\Projects\SourceCode\Learning\learn\src\com\learn\oracle\LearningJavaLang\ClassesAndObject\LamdaExpression>javap -v LambdaByteCodeAnalysis2
Classfile /C:/E_Drive/Projects/SourceCode/Learning/learn/src/com/learn/oracle/LearningJavaLang/ClassesAndObject/LamdaExpression/LambdaByteCodeAnalysis2.class
  Last modified 15 Aug, 2018; size 1639 bytes
  MD5 checksum 7e61b6b121ba9d8097f4034f331df1c9
  Compiled from "LambdaByteCodeAnalysis2.java"
public class LambdaByteCodeAnalysis2
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #17.#33        // java/lang/Object."<init>":()V
   #2 = Methodref          #16.#34        // LambdaByteCodeAnalysis2.testConsumer:()V
   #3 = InvokeDynamic      #0:#39         // #0:accept:(I)Ljava/util/function/Consumer;
   #4 = Methodref          #16.#40        // LambdaByteCodeAnalysis2.testConsumerImpl:(Ljava/util/function/Consumer;)V
   #5 = String             #24            // testConsumer
   #6 = InterfaceMethodref #41.#42        // java/util/function/Consumer.accept:(Ljava/lang/Object;)V
   #7 = Fieldref           #43.#44        // java/lang/System.out:Ljava/io/PrintStream;
   #8 = Class              #45            // java/lang/StringBuilder
   #9 = Methodref          #8.#33         // java/lang/StringBuilder."<init>":()V
  #10 = String             #46            // Hello, Mr.
  #11 = Methodref          #8.#47         // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #12 = Methodref          #8.#48         // java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
  #13 = Methodref          #8.#49         // java/lang/StringBuilder.toString:()Ljava/lang/String;
  #14 = Methodref          #50.#51        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #15 = Methodref          #50.#52        // java/io/PrintStream.println:(I)V
  #16 = Class              #53            // LambdaByteCodeAnalysis2
  #17 = Class              #54            // java/lang/Object
  #18 = Utf8               <init>
  #19 = Utf8               ()V
  #20 = Utf8               Code
  #21 = Utf8               LineNumberTable
  #22 = Utf8               main
  #23 = Utf8               ([Ljava/lang/String;)V
  #24 = Utf8               testConsumer
  #25 = Utf8               testConsumerImpl
  #26 = Utf8               (Ljava/util/function/Consumer;)V
  #27 = Utf8               Signature
  #28 = Utf8               (Ljava/util/function/Consumer<Ljava/lang/Object;>;)V
  #29 = Utf8               lambda$testConsumer$0
  #30 = Utf8               (ILjava/lang/Object;)V
  #31 = Utf8               SourceFile
  #32 = Utf8               LambdaByteCodeAnalysis2.java
  #33 = NameAndType        #18:#19        // "<init>":()V
  #34 = NameAndType        #24:#19        // testConsumer:()V
  #35 = Utf8               BootstrapMethods
  #36 = MethodHandle       #6:#55         // invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/Stri
ng;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #37 = MethodType         #56            //  (Ljava/lang/Object;)V
  #38 = MethodHandle       #6:#57         // invokestatic LambdaByteCodeAnalysis2.lambda$testConsumer$0:(ILjava/lang/Object;)V
  #39 = NameAndType        #58:#59        // accept:(I)Ljava/util/function/Consumer;
  #40 = NameAndType        #25:#26        // testConsumerImpl:(Ljava/util/function/Consumer;)V
  #41 = Class              #60            // java/util/function/Consumer
  #42 = NameAndType        #58:#56        // accept:(Ljava/lang/Object;)V
  #43 = Class              #61            // java/lang/System
  #44 = NameAndType        #62:#63        // out:Ljava/io/PrintStream;
  #45 = Utf8               java/lang/StringBuilder
  #46 = Utf8               Hello, Mr.
  #47 = NameAndType        #64:#65        // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #48 = NameAndType        #64:#66        // append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
  #49 = NameAndType        #67:#68        // toString:()Ljava/lang/String;
  #50 = Class              #69            // java/io/PrintStream
  #51 = NameAndType        #70:#71        // println:(Ljava/lang/String;)V
  #52 = NameAndType        #70:#72        // println:(I)V
  #53 = Utf8               LambdaByteCodeAnalysis2
  #54 = Utf8               java/lang/Object
  #55 = Methodref          #73.#74        // java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang
/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #56 = Utf8               (Ljava/lang/Object;)V
  #57 = Methodref          #16.#75        // LambdaByteCodeAnalysis2.lambda$testConsumer$0:(ILjava/lang/Object;)V
  #58 = Utf8               accept
  #59 = Utf8               (I)Ljava/util/function/Consumer;
  #60 = Utf8               java/util/function/Consumer
  #61 = Utf8               java/lang/System
  #62 = Utf8               out
  #63 = Utf8               Ljava/io/PrintStream;
  #64 = Utf8               append
  #65 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
  #66 = Utf8               (Ljava/lang/Object;)Ljava/lang/StringBuilder;
  #67 = Utf8               toString
  #68 = Utf8               ()Ljava/lang/String;
  #69 = Utf8               java/io/PrintStream
  #70 = Utf8               println
  #71 = Utf8               (Ljava/lang/String;)V
  #72 = Utf8               (I)V
  #73 = Class              #76            // java/lang/invoke/LambdaMetafactory
  #74 = NameAndType        #77:#81        // metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invok
e/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #75 = NameAndType        #29:#30        // lambda$testConsumer$0:(ILjava/lang/Object;)V
  #76 = Utf8               java/lang/invoke/LambdaMetafactory
  #77 = Utf8               metafactory
  #78 = Class              #83            // java/lang/invoke/MethodHandles$Lookup
  #79 = Utf8               Lookup
  #80 = Utf8               InnerClasses
  #81 = Utf8               (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke
/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #82 = Class              #84            // java/lang/invoke/MethodHandles
  #83 = Utf8               java/lang/invoke/MethodHandles$Lookup
  #84 = Utf8               java/lang/invoke/MethodHandles
{
  public LambdaByteCodeAnalysis2();
    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 3: 0

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=0, locals=1, args_size=1
         0: invokestatic  #2                  // Method testConsumer:()V
         3: return
      LineNumberTable:
        line 6: 0
        line 7: 3
}
SourceFile: "LambdaByteCodeAnalysis2.java"
InnerClasses:
     public static final #79= #78 of #82; //Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
BootstrapMethods:
  0: #36 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljav
a/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #37 (Ljava/lang/Object;)V
      #38 invokestatic LambdaByteCodeAnalysis2.lambda$testConsumer$0:(ILjava/lang/Object;)V
      #37 (Ljava/lang/Object;)V

C:\E_Drive\Projects\SourceCode\Learning\learn\src\com\learn\oracle\LearningJavaLang\ClassesAndObject\LamdaExpression>

LambdaByteCodeAnalysis3.class

C:\E_Drive\Projects\SourceCode\Learning\learn\src\com\learn\oracle\LearningJavaLang\ClassesAndObject\LamdaExpression>javap -v LambdaByteCodeAnalysis3
Classfile /C:/E_Drive/Projects/SourceCode/Learning/learn/src/com/learn/oracle/LearningJavaLang/ClassesAndObject/LamdaExpression/LambdaByteCodeAnalysis3.class
  Last modified 15 Aug, 2018; size 1742 bytes
  MD5 checksum 18bf579a4a95e700e29ec7e35bbac1b4
  Compiled from "LambdaByteCodeAnalysis3.java"
public class LambdaByteCodeAnalysis3
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #19.#37        // java/lang/Object."<init>":()V
   #2 = Fieldref           #4.#38         // LambdaByteCodeAnalysis3.testing:I
   #3 = Methodref          #4.#39         // LambdaByteCodeAnalysis3.testConsumer:()V
   #4 = Class              #40            // LambdaByteCodeAnalysis3
   #5 = Methodref          #4.#37         // LambdaByteCodeAnalysis3."<init>":()V
   #6 = InvokeDynamic      #0:#45         // #0:accept:(LLambdaByteCodeAnalysis3;)Ljava/util/function/Consumer;
   #7 = Methodref          #4.#46         // LambdaByteCodeAnalysis3.testConsumerImpl:(Ljava/util/function/Consumer;)V
   #8 = String             #28            // testConsumer
   #9 = InterfaceMethodref #47.#48        // java/util/function/Consumer.accept:(Ljava/lang/Object;)V
  #10 = Fieldref           #49.#50        // java/lang/System.out:Ljava/io/PrintStream;
  #11 = Class              #51            // java/lang/StringBuilder
  #12 = Methodref          #11.#37        // java/lang/StringBuilder."<init>":()V
  #13 = String             #52            // Hello, Mr.
  #14 = Methodref          #11.#53        // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #15 = Methodref          #11.#54        // java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
  #16 = Methodref          #11.#55        // java/lang/StringBuilder.toString:()Ljava/lang/String;
  #17 = Methodref          #56.#57        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #18 = Methodref          #56.#58        // java/io/PrintStream.println:(I)V
  #19 = Class              #59            // java/lang/Object
  #20 = Utf8               testing
  #21 = Utf8               I
  #22 = Utf8               <init>
  #23 = Utf8               ()V
  #24 = Utf8               Code
  #25 = Utf8               LineNumberTable
  #26 = Utf8               main
  #27 = Utf8               ([Ljava/lang/String;)V
  #28 = Utf8               testConsumer
  #29 = Utf8               testConsumerImpl
  #30 = Utf8               (Ljava/util/function/Consumer;)V
  #31 = Utf8               Signature
  #32 = Utf8               (Ljava/util/function/Consumer<Ljava/lang/Object;>;)V
  #33 = Utf8               lambda$testConsumer$0
  #34 = Utf8               (LLambdaByteCodeAnalysis3;Ljava/lang/Object;)V
  #35 = Utf8               SourceFile
  #36 = Utf8               LambdaByteCodeAnalysis3.java
  #37 = NameAndType        #22:#23        // "<init>":()V
  #38 = NameAndType        #20:#21        // testing:I
  #39 = NameAndType        #28:#23        // testConsumer:()V
  #40 = Utf8               LambdaByteCodeAnalysis3
  #41 = Utf8               BootstrapMethods
  #42 = MethodHandle       #6:#60         // invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/Stri
ng;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #43 = MethodType         #61            //  (Ljava/lang/Object;)V
  #44 = MethodHandle       #6:#62         // invokestatic LambdaByteCodeAnalysis3.lambda$testConsumer$0:(LLambdaByteCodeAnalysis3;Ljava/lang/Object;)V
  #45 = NameAndType        #63:#64        // accept:(LLambdaByteCodeAnalysis3;)Ljava/util/function/Consumer;
  #46 = NameAndType        #29:#30        // testConsumerImpl:(Ljava/util/function/Consumer;)V
  #47 = Class              #65            // java/util/function/Consumer
  #48 = NameAndType        #63:#61        // accept:(Ljava/lang/Object;)V
  #49 = Class              #66            // java/lang/System
  #50 = NameAndType        #67:#68        // out:Ljava/io/PrintStream;
  #51 = Utf8               java/lang/StringBuilder
  #52 = Utf8               Hello, Mr.
  #53 = NameAndType        #69:#70        // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #54 = NameAndType        #69:#71        // append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
  #55 = NameAndType        #72:#73        // toString:()Ljava/lang/String;
  #56 = Class              #74            // java/io/PrintStream
  #57 = NameAndType        #75:#76        // println:(Ljava/lang/String;)V
  #58 = NameAndType        #75:#77        // println:(I)V
  #59 = Utf8               java/lang/Object
  #60 = Methodref          #78.#79        // java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang
/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #61 = Utf8               (Ljava/lang/Object;)V
  #62 = Methodref          #4.#80         // LambdaByteCodeAnalysis3.lambda$testConsumer$0:(LLambdaByteCodeAnalysis3;Ljava/lang/Object;)V
  #63 = Utf8               accept
  #64 = Utf8               (LLambdaByteCodeAnalysis3;)Ljava/util/function/Consumer;
  #65 = Utf8               java/util/function/Consumer
  #66 = Utf8               java/lang/System
  #67 = Utf8               out
  #68 = Utf8               Ljava/io/PrintStream;
  #69 = Utf8               append
  #70 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
  #71 = Utf8               (Ljava/lang/Object;)Ljava/lang/StringBuilder;
  #72 = Utf8               toString
  #73 = Utf8               ()Ljava/lang/String;
  #74 = Utf8               java/io/PrintStream
  #75 = Utf8               println
  #76 = Utf8               (Ljava/lang/String;)V
  #77 = Utf8               (I)V
  #78 = Class              #81            // java/lang/invoke/LambdaMetafactory
  #79 = NameAndType        #82:#86        // metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invok
e/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #80 = NameAndType        #33:#34        // lambda$testConsumer$0:(LLambdaByteCodeAnalysis3;Ljava/lang/Object;)V
  #81 = Utf8               java/lang/invoke/LambdaMetafactory
  #82 = Utf8               metafactory
  #83 = Class              #88            // java/lang/invoke/MethodHandles$Lookup
  #84 = Utf8               Lookup
  #85 = Utf8               InnerClasses
  #86 = Utf8               (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke
/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #87 = Class              #89            // java/lang/invoke/MethodHandles
  #88 = Utf8               java/lang/invoke/MethodHandles$Lookup
  #89 = Utf8               java/lang/invoke/MethodHandles
{
  int testing;
    descriptor: I
    flags:

  public LambdaByteCodeAnalysis3();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: aload_0
         5: iconst_0
         6: putfield      #2                  // Field testing:I
         9: return
      LineNumberTable:
        line 3: 0
        line 5: 4

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=0, locals=1, args_size=1
         0: invokestatic  #3                  // Method testConsumer:()V
         3: return
      LineNumberTable:
        line 8: 0
        line 9: 3
}
SourceFile: "LambdaByteCodeAnalysis3.java"
InnerClasses:
     public static final #84= #83 of #87; //Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
BootstrapMethods:
  0: #42 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljav
a/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #43 (Ljava/lang/Object;)V
      #44 invokestatic LambdaByteCodeAnalysis3.lambda$testConsumer$0:(LLambdaByteCodeAnalysis3;Ljava/lang/Object;)V
      #43 (Ljava/lang/Object;)V

C:\E_Drive\Projects\SourceCode\Learning\learn\src\com\learn\oracle\LearningJavaLang\ClassesAndObject\LamdaExpression>

2 个答案:

答案 0 :(得分:2)

Java Language Specification 说:

  

与出现在匿名类声明中的代码不同,lambda正文中出现的名称以及thissuper关键字的含义以及引用声明的可访问性与周围环境相同上下文(lambda参数引入新名称除外)。

     

lambda表达式主体中的this(包括显式和隐式)的透明性(即,与周围环境中相同)将为实现提供更大的灵活性,并防止不合格的含义体内的名称不依赖于重载分辨率。

     

实际上,lambda表达式需要谈论自己(以递归方式调用其自身或调用其其他方法)是不寻常的,而更常见的是想使用名称来指代外壳中的事物否则会被遮盖的类(thistoString())。如果有必要让lambda表达式引用自身(就像通过this一样),则应改用方法引用或匿名内部类。

答案 1 :(得分:1)

我的回答和简单的逻辑是,由于this用于引用对象的状态,而lambda表达式没有任何状态(也捕获了外部变量访问),所以没有意义this引用了lambda表达式的对象。