Consider the following Java 8 snippet.
public static void main(String[] args) {                List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);     Consumer<Integer>  consumer = x -> System.out.print(x);       integers.forEach(consumer); }   What is Consumer<Integer> consumer = x -> System.out.print(x) getting compiled to?
I understand that Lambdas are not implemented as anonymous inner classes. However Consumer<Integer> is an interface therefore x -> System.out.print(x) must be producing an object of some kind but it is not clear what kind of object is being produced.
Is there some new type of object in Java 8 to represent a lambda expression?
Update Here is the decompiled program the program was complied with the eclipse java 8 complier and the output below is from eclipse when you open a class file.
It looks like that the lambda expression is getting turned into a static method on the class that contains the lambda expression private static synthetic void lambda$0(java.lang.Integer x);
// Compiled from Example.java (version 1.8 : 52.0, super bit) public class Example {    // Method descriptor #6 ()V   // Stack: 1, Locals: 1   public Example();     0  aload_0 [this]     1  invokespecial java.lang.Object() [8]     4  return       Line numbers:         [pc: 0, line: 7]       Local variable table:         [pc: 0, pc: 5] local: this index: 0 type: Example    // Method descriptor #15 ([Ljava/lang/String;)V   // Stack: 4, Locals: 3   public static void main(java.lang.String[] args);      0  iconst_5      1  anewarray java.lang.Integer [16]      4  dup      5  iconst_0      6  iconst_1      7  invokestatic java.lang.Integer.valueOf(int) : java.lang.Integer [18]     10  aastore     11  dup     12  iconst_1     13  iconst_2     14  invokestatic java.lang.Integer.valueOf(int) : java.lang.Integer [18]     17  aastore     18  dup     19  iconst_2     20  iconst_3     21  invokestatic java.lang.Integer.valueOf(int) : java.lang.Integer [18]     24  aastore     25  dup     26  iconst_3     27  iconst_4     28  invokestatic java.lang.Integer.valueOf(int) : java.lang.Integer [18]     31  aastore     32  dup     33  iconst_4     34  iconst_5     35  invokestatic java.lang.Integer.valueOf(int) : java.lang.Integer [18]     38  aastore     39  invokestatic java.util.Arrays.asList(java.lang.Object[]) : java.util.List [22]     42  astore_1 [integers]     43  invokedynamic 0 accept() : java.util.function.Consumer [31]     48  astore_2 [consumer]     49  getstatic java.lang.System.out : java.io.PrintStream [32]     52  aload_2 [consumer]     53  invokevirtual java.lang.Object.getClass() : java.lang.Class [38]     56  invokevirtual java.lang.Class.getCanonicalName() : java.lang.String [42]     59  invokevirtual java.io.PrintStream.println(java.lang.String) : void [48]     62  getstatic java.lang.System.out : java.io.PrintStream [32]     65  aload_2 [consumer]     66  invokevirtual java.lang.Object.getClass() : java.lang.Class [38]     69  invokevirtual java.lang.Class.getTypeName() : java.lang.String [54]     72  invokevirtual java.io.PrintStream.println(java.lang.String) : void [48]     75  aload_1 [integers]     76  aload_2 [consumer]     77  invokeinterface java.util.List.forEach(java.util.function.Consumer) : void [57] [nargs: 2]     82  return       Line numbers:         [pc: 0, line: 10]         [pc: 43, line: 12]         [pc: 49, line: 14]         [pc: 62, line: 15]         [pc: 75, line: 17]         [pc: 82, line: 18]       Local variable table:         [pc: 0, pc: 83] local: args index: 0 type: java.lang.String[]         [pc: 43, pc: 83] local: integers index: 1 type: java.util.List         [pc: 49, pc: 83] local: consumer index: 2 type: java.util.function.Consumer       Local variable type table:         [pc: 43, pc: 83] local: integers index: 1 type: java.util.List<java.lang.Integer>         [pc: 49, pc: 83] local: consumer index: 2 type: java.util.function.Consumer<java.lang.Integer>    // Method descriptor #73 (Ljava/lang/Integer;)V   // Stack: 2, Locals: 1   private static synthetic void lambda$0(java.lang.Integer x);     0  getstatic java.lang.System.out : java.io.PrintStream [32]     3  aload_0 [x]     4  invokevirtual java.io.PrintStream.print(java.lang.Object) : void [74]     7  return       Line numbers:         [pc: 0, line: 12]       Local variable table:         [pc: 0, pc: 8] local: x index: 0 type: java.lang.Integer    Inner classes:     [inner class info: #96 java/lang/invoke/MethodHandles$Lookup, outer class info: #98 java/lang/invoke/MethodHandles      inner name: #100 Lookup, accessflags: 25 public static final] Bootstrap methods:   0 : # 89 arguments: {#90,#93,#94} } 
                Lambda Expressions were added in Java 8. A lambda expression is a short block of code which takes in parameters and returns a value. Lambda expressions are similar to methods, but they do not need a name and they can be implemented right in the body of a method.
The value of a lambda expression is a reference to an instance of a class with the following properties: The class implements the targeted functional interface and, if the target type is an intersection type, every other interface element of the intersection.
For Lambda expressions, the compiler doesn't translate them into something which is already understood by JVM. Lambda syntax that is written by the developer is desugared into JVM level instructions generated during compilation, which means the actual responsibility of constructing lambda is deferred to runtime.
One way I can reuse this lambda expression is if there is some interface/class which is a parent of all lambda expressions such that I can assign any lambda expression to a reference of such an interface/class.
The current draft of the Java 8 Language Specification states (chapter 15.27.4)
The value of a lambda expression is a reference to an instance of a class with the following properties:
- The class implements the targeted functional interface and, if the target type is an intersection type, every other interface element of the intersection.
 - The class declares a method that overrides the functional interface supertype's abstract methods (and, potentially, some other methods of its superinterfaces).
 - The method's parameter types, return type, and thrown types are given by the interface's function type.
 - The method's body has the effect of evaluating the lambda body, if it is an expression, or of executing the lambda body, if it is a block; if a result is expected, it is returned from the method.
 - The class overrides no other methods of the interface or interfaces mentioned above, except that it may override methods of the
 Objectclass.
Note that the JLS doesn't say anything about how the code should be compiled except that the byte code should support the specification above.
As such, the object returned by the lambda expression
x -> System.out.print(x);     will be an instance of a class that follows the above rules.
Given your comment that
consumer.getClass()   returns the following class
Example$$Lambda$1/1072591677   it seems that it is generating a proxy-like class specific for lambda expressions.
See here:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With