2014-04-17 19 views
18

Próbuję utworzyć przykład za pomocą wyrażenia lambda w java i używam Offical JDK8. Mój przykład został pomyślnie uruchomiony. Ale kiedy próbuje sprawdzić jak kompilator przetłumaczyć wyrażenie lambda do kodu bajtowego, to sprawia, że ​​niektóre confusion.Following jest kod mojego przykład: -Jak wyrażeń lambdy są tłumaczone w Java Byte Code

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)); 
    } 
} 

W tym Article, dyskutują o tym, jak kompilator przetłumaczyć lambda wyrażenia do kodu bajtowego. Zgodnie z tym dokumentem wyrażenie lambda przekształca się w metodę static i miejsce, w którym deklaruje się wyrażenie lambda, ma odniesienie do metody lambda static. Następujący przykład znajduje się w artykule:

//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); 
    } 
} 

Mój przykład działa dobrze i daje nam odpowiedni wynik. Ale gdy próbuję uruchomić komendę javap w celu sprawdzenia kodu bajtów klasy, nie ma statycznej metody dla lambdas w kodzie bajtowym.

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[]); 
} 

W przypadku leków generycznych, metoda most jest tworzony przez kompilator i będziemy również sprawdzić tę metodę przy użyciu polecenia javap, ale w przypadku lambda nie ma static metoda. Artykuł został opublikowany w 2012 roku i Java 8 było uruchomienie w marcu 2014 roku, więc mam kilka pytań dotyczących ponadnarodowym lambda:

  1. Czy istnieje nowa realizacja wykorzystywane do lambda w JDK 8 po tej wersji artykułu lub zrobię coś nie tak, aby sprawdzić metodę lambda?
  2. Jak naprawdę kompilator radzi sobie z wyrażeniem lambda?
  3. W jaki sposób JVM odwołuje się do wygaśnięcia lambda?

Odpowiedz

17

Zastosowanie javap dodatkowe argumenty, aby wydrukować pełną informację o klasie: javap -v -s -p -c

Na swoim przykładzie, kod źródłowy lambda będzie:

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; 
} 
Powiązane problemy