2014-04-17 7 views
18

में लैम्ब्डा अभिव्यक्तियों का अनुवाद कैसे किया जाता है मैं जावा में लैम्ब्डा अभिव्यक्ति का उपयोग करके एक उदाहरण बनाने की कोशिश कर रहा हूं और मैं ऑफिकल जेडीके 8 का उपयोग कर रहा हूं। मेरा उदाहरण सफलतापूर्वक चलाया गया था। लेकिन जब मैं कैसे संकलक बाइट कोड में लैम्ब्डा अभिव्यक्ति का अनुवाद जांच करते हुए, यह मुझे बनाता है कुछ confusion.Following मेरी उदाहरण के कोड है: -जावा बाइट कोड

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

इस Article में, वे कैसे संकलक लैम्ब्डा का अनुवाद के बारे में चर्चा बाइट कोड में अभिव्यक्तियाँ। इस दस्तावेज़ के अनुसार लैम्ब्डा अभिव्यक्ति static विधि में परिवर्तित होती है और उस स्थान पर जहां लैम्ब्डा अभिव्यक्ति घोषित करती है, में लैम्ब्डा static विधि का संदर्भ है। निम्नलिखित उदाहरण आलेख में है:

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

मेरा उदाहरण ठीक है और हमें उचित परिणाम दें। लेकिन जब मैं कक्षा के बाइट कोड को चेक करने के लिए javap कमांड चलाने की कोशिश करता हूं, तो बाइट कोड में लैम्बडास के लिए कोई स्थिर विधि नहीं है।

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

जेनरिक के मामले में, पुल विधि संकलक द्वारा बनाई गई है और हम भी इस विधि javap आदेश का उपयोग कर जाँच करेगा, लेकिन lambdas के मामले में कोई static विधि नहीं है। लेख 2012 और जावा 8 में प्रकाशित किया गया था मार्च 2014 में लांच किया गया था तो मैं लैम्ब्डा की अंतरराष्ट्रीय संबंध में कुछ पूछना चाहते हैं:

  1. कोई नया इस लेख रिलीज होने के बाद JDK 8 में लैम्ब्डा के लिए इस्तेमाल किया कार्यान्वयन है या मैं क्या करेंगे लैम्ब्डा विधि की जांच करने में कुछ गड़बड़ है?
  2. लैम्ब्डा अभिव्यक्ति के साथ संकलक वास्तव में कैसे काम करता है?
  3. कैसे JVM लैम्ब्डा अवसाद का आह्वान करता है?

उत्तर

17

उपयोग javap अतिरिक्त तर्क वर्ग के बारे में पूरी जानकारी मुद्रित करने के लिए: javap -v -p -s -c

अपने उदाहरण के लिए, लैम्ब्डा के स्रोत कोड होगा:

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; 
} 
संबंधित मुद्दे