Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Lambda Expressions Are Translate In Java Byte Code

Tags:

I am trying to create an example using lambda expression in java and i am using offical JDK8. My example was run successfully. But when i trying to check how the compiler translate lambda expression into byte code, this makes me some confusion.Following is the code of my example:-

public class LambdaTest {
    public Integer lambdaBinaryOpertor(BinaryOperator<Integer> binaryOperator) {
        return binaryOperator.apply(60, 72);
    }

    public static void main(String[] args) {
        LambdaTest test = new LambdaTest();
        BinaryOperator<Integer> binaryOperator = (a, b) -> a*b;
        System.out.println("Additon using Lambda BinaryOperator: "+test.lambdaBinaryOpertor(binaryOperator));
    }
}

In this Article, they discuss about how compiler translate the lambda expressions into byte code. According to this document the lambda expression convert into static method and the location where lambda expression declare, have reference of lambda static method. The following example is in the article :

//Source code
class A {
    public void foo() {
        List<String> list = ...
        list.forEach( s -> { System.out.println(s); } );
    }
} 

//After compile above code "translate code " 
class A {
    public void foo() {
        List<String> list = ...
        list.forEach( [lambda for lambda$1 as Block] );
    }

    static void lambda$1(String s) {
        System.out.println(s);
    }
}

My example run fine and give us the appropriate result. But when i trying to run the javap command for check the byte code of class, there is no static method for lambdas in byte code.

c:\>javap LambdaTest
Compiled from "LambdaTest.java"
public class LambdaTest {
public LambdaTest();
public java.lang.Integer lambdaBinaryOpertor(java.util.function.BinaryOperator <java.lang.Integer>);
public static void main(java.lang.String[]);
}

In the case of generics, bridge method is created by compiler and we will also check this method using javap command, but in the case of lambdas there is no static method. The article was published at 2012 and java 8 was launch at march 2014. So i have some queries regarding transnational of lambda:

  1. Is there any new implementation used for lambda in JDK 8 after this article release or i will do something wrong to check the lambda method ?
  2. How really the compiler deal with lambda expression?
  3. How the JVM invoke the lambda exression ?
like image 865
Harmeet Singh Taara Avatar asked Apr 17 '14 12:04

Harmeet Singh Taara


People also ask

How does lambda expression work in Java?

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.

How is lambda expression represented by JVM?

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.

What converts code to byte code in Java?

Compiler converts the source code or the Java program into the Byte Code(or machine code), and secondly, the Interpreter executes the byte code on the system. The Interpreter can also be called JVM(Java Virtual Machine).


1 Answers

Use javap additional arguments to print full information about class: javap -v -p -s -c

For your example, source code of lambda will be:

private static java.lang.Integer lambda$main$0(java.lang.Integer, java.lang.Integer);
    descriptor: (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;
    flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0       
         1: invokevirtual #17                 // Method java/lang/Integer.intValue:()I
         4: aload_1       
         5: invokevirtual #17                 // Method java/lang/Integer.intValue:()I
         8: imul          
         9: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        12: areturn       
      LineNumberTable:
        line 10: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      13     0     a   Ljava/lang/Integer;
            0      13     1     b   Ljava/lang/Integer;
}
like image 79
Ivan Babanin Avatar answered Sep 26 '22 12:09

Ivan Babanin