1

I felt lot of confusion on whether there is an object associated with lambda expression or not because it is said that “this” in case of lambda expression doesn’t refer to the object of the lambda expression because lambda expression doesn’t have any object but again it is said that if lambda expression doesn’t capture the variables from outside scope then same singleton object will be used for each invocation of lambda expression.

Now, I am assuming that there will be an object associated with the lambda expression (I guess this answers my first question, you guys please correct me if I am wrong), so my question is that then why “this” doesn’t refer to the object of lambda expression, much like what happens in case of anonymous class.


UPDATES: My 3 test classes:
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");
    }

}

Now, bytecode in same order:

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>
pjj
  • 2,015
  • 1
  • 17
  • 42

2 Answers2

2

The Java Language Specification sais this:

Unlike code appearing in anonymous class declarations, the meaning of names and the this and super keywords appearing in a lambda body, along with the accessibility of referenced declarations, are the same as in the surrounding context (except that lambda parameters introduce new names).

The transparency of this (both explicit and implicit) in the body of a lambda expression - that is, treating it the same as in the surrounding context - allows more flexibility for implementations, and prevents the meaning of unqualified names in the body from being dependent on overload resolution.

Practically speaking, it is unusual for a lambda expression to need to talk about itself (either to call itself recursively or to invoke its other methods), while it is more common to want to use names to refer to things in the enclosing class that would otherwise be shadowed (this, toString()). If it is necessary for a lambda expression to refer to itself (as if via this), a method reference or an anonymous inner class should be used instead.

Community
  • 1
  • 1
Johannes Kuhn
  • 14,778
  • 4
  • 49
  • 73
  • Please correct me for my first question that an object will be created for lambda expression - but whether a new object will be created each time will depend, right? – pjj Aug 13 '18 at 20:09
  • Well, if a new object is created depends on the implementation of lambda factory. – Johannes Kuhn Aug 13 '18 at 20:13
  • 1
    @that is easy to verify - write a capturing lambda and a non-capturing lambda and see the generated classes... – Eugene Aug 13 '18 at 20:17
  • @Eugene - may be if you would like put your answer with details? – pjj Aug 13 '18 at 20:23
  • @pjj no, this was present on SO 100%, just search for it. "Will lambda create an instance on the heap"... very first result – Eugene Aug 13 '18 at 20:25
  • @Eugene: ok, thanks for the pointer – pjj Aug 13 '18 at 20:27
  • The generated classes are identical. A lambda is first desuggared into a (private) method, and at the old place an `invokedynamic` call is placed. The arguments for the dynamic call are the captured variables. – Johannes Kuhn Aug 13 '18 at 21:14
  • @Eugene I searched https://stackoverflow.com/questions/27524445/does-a-lambda-expression-create-an-object-on-the-heap-every-time-its-executed and this doesn't answer my question (along with bytecode analysis) that whether object will be generated or not. – pjj Aug 14 '18 at 20:43
  • @Eugene So, I created my own classes and tried some hands with bytecode analysis but I am not able to figure out the things .. if you have little time then can you help ... I have updated my code and bytecode in my question ... – pjj Aug 14 '18 at 20:44
  • @JohannesKuhn I generated the bytecode and I do not see `dynamicinvocation` instruction ... if you hv little time then can you help figuring out the things ... – pjj Aug 14 '18 at 20:45
  • @JohannesKuhn I am even not able to figure out the new method you talked about, which would have the lambda expressoin code – pjj Aug 14 '18 at 20:46
  • @pjj https://stackoverflow.com/a/45393978/1059372 – Eugene Aug 14 '18 at 20:47
  • @Eugene Ok thanks, let me go through it. – pjj Aug 14 '18 at 20:50
  • @Eugene I think I am missing something, I do not see dynamicinvocation instruction in my byte code, something like this `20: invokedynamic #11, 0` which is in that answer ... I guess I am missing something .... I generated bytecode as `javap -v ........` ... I think it is my unfamiliarity with bytecode that I am not able to understand the things ... – pjj Aug 14 '18 at 21:00
  • 1
    @pjj probably `javap -c -p` also.. but if you can't read byte code this is going to be hard to understand – Eugene Aug 14 '18 at 21:01
  • @Eugene Thanks, I generated with those arguments and this time bytecode was looking much simpler and I could understand few things .. I could see that if local variable is used in LE then bootstrap method had captured those variables and if instance variables are used in LE and LE had captured the instance of the class .. however if could not figure out and see deterministically that an object is created for lambda expression .... – pjj Aug 14 '18 at 21:55
  • The real "magic" happens in `java.lang.invoke.MetaLambdaFactory`.The invokedynamic instruction will call the bootstrap method when it is called the first time, and the bootstrap method returns a `CallSite`. A naive implementation would create an (anonymous) class and use the MethodHandle of the constructor for the call site. But if you know that the constructor does not take any arguments, you could also return a [constant method handle](https://docs.oracle.com/javase/10/docs/api/java/lang/invoke/MethodHandles.html#constant(java.lang.Class,java.lang.Object)). – Johannes Kuhn Aug 15 '18 at 00:55
  • @JohannesKuhn Ok, thank much for your inputs. I have more questions about how LE internally works, I will post another question for that. – pjj Aug 16 '18 at 21:31
1

My answer and simple logic would be that since this is used to refer to the state of the object and lambda expressions doesn’t have any state (outside variable access is also captured) so there is no point of having this referring to the object of lambda expression.

hagrawal7777
  • 14,103
  • 5
  • 40
  • 70