usar funciones expresiones explicacion example como arquitectura anonimas java lambda jvm java-8 compiler-theory

funciones - Cómo se convierten las expresiones Lambda en código de bytes de Java



java 8 lambda explicacion (1)

Use argumentos adicionales de javap para imprimir información completa sobre la clase: javap -v -p -s -c

Para su ejemplo, el código fuente de lambda será:

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

Intento crear un ejemplo usando la expresión lambda en java y estoy usando el JDK8 oficial. Mi ejemplo se ejecutó con éxito. Pero cuando trato de verificar cómo el compilador convierte la expresión lambda en código de bytes, esto me da cierta confusión. Seguir es el código de mi ejemplo: -

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

En este artículo , discuten cómo el compilador traduce las expresiones lambda en código de bytes. De acuerdo con este documento, la expresión lambda se convierte en método static y la ubicación donde la expresión lambda declara, tiene referencia del método lambda static . El siguiente ejemplo está en el artículo:

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

Mi ejemplo funciona bien y nos da el resultado apropiado. Pero cuando trato de ejecutar el comando javap para verificar el código de byte de la clase, no hay un método estático para lambdas en el código de bytes.

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

En el caso de los genéricos, el método de puente es creado por el compilador y también comprobaremos este método utilizando el comando javap , pero en el caso de lambdas no hay un método static . El artículo se publicó en 2012 y Java 8 se lanzó en marzo de 2014. Por lo tanto, tengo algunas dudas sobre la transnacional de lambda:

  1. ¿Hay alguna implementación nueva utilizada para lambda en JDK 8 después de la publicación de este artículo o haré algo mal para verificar el método lambda?
  2. ¿De qué manera el compilador lidia con la expresión lambda?
  3. ¿Cómo invocó la JVM la extenuación lambda?