2015-11-13 8 views
8

मैंने अभी ग्रहण में एक त्वरित प्रयोग किया है।विधि संदर्भ बनाम lambdas का उपयोग करते समय स्टैक निशान कम navigable हैं?

public class StackTractTest { 

    static class Nasty { 
    public Integer toInt() { 
     if (1 == 1) throw new RuntimeException(); 
     return 1; 
    } 
    } 

    @Test 
    public void methodReference() { 
    Stream.of(new Nasty()) 
     .map(Nasty::toInt) 
     .findFirst(); 
    } 

    @Test 
    public void lambda() { 
    Stream.of(new Nasty()) 
     .map(n -> n.toInt()) 
     .findFirst(); 
    } 

} 

जब विधि-संदर्भ परीक्षण विफल रहता है, का पता लगाने के लिए शुरू होता

java.lang.RuntimeException 
    at com.example.StackTractTest$Nasty.toInt(StackTractTest.java:11) 
    at com.example.StackTractTest$$Lambda$1/1681433494.apply(Unknown Source) 
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) 

कोई जिस पर विधि संदर्भ हालांकि ट्रेस (दिखाया गया है) के अंत प्रयोग किया जाता है लाइन के लिए वापस संदर्भ है findFirst पर लाइन पर वापस लिंक करता है।

lamdba स्टैकट्रेस शुरू होता है जबकि

java.lang.RuntimeException 
    at com.example.StackTractTest$Nasty.toInt(StackTractTest.java:11) 
    at com.example.StackTractTest.lambda$0(StackTractTest.java:26) 
    at com.example.StackTractTest$$Lambda$1/1681433494.apply(Unknown Source) 
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) 

कौन सा सही ढंग से लैम्ब्डा की पहचान करता है लाइन 26.

पर इस्तेमाल किया गया था इस ग्रहण संकलक की एक विशेष लक्षण है या इस विधि संदर्भों का उपयोग की एक सामान्य नुकसान है कि उन्हें और एक भेड़ का बच्चा चुनने पर विचार किया जाना चाहिए?

+2

नहीं, यह जावा से कैसे आता है। वे स्टैक-ट्रेस अनुभव –

+1

में सुधार करने पर काम कर रहे हैं मैंने कभी डेवलपर को लंबे समय तक स्टैक ट्रेस मांगने के लिए नहीं सुना है ... – Holger

उत्तर

4

नहीं, इस प्रकार यह वर्तमान में लागू किया गया है।

के हवाले से a paper लैम्ब्डा अभिव्यक्ति के अनुवाद के बारे में ब्रायन गोएज़ द्वारा लिखित:

संकलक एक लैम्ब्डा अभिव्यक्ति का सामना करना पड़ता है, यह पहले कम हो (desugars) लैम्ब्डा एक विधि जिसका तर्क सूची और वापसी प्रकार मैच में शरीर लैम्ब्डा अभिव्यक्ति

...

विधि संदर्भ लैम्ब्डा अभिव्यक्ति के रूप में एक ही तरह से व्यवहार कर रहे हैं, सिवाय इसके कि सबसे विधि संदर्भ एक नई पद्धति में desugared किए जाने की जरूरत नहीं है, की है कि; हम संदर्भित विधि के लिए बस एक स्थिर विधि हैंडल लोड कर सकते हैं और मेटाफैक्टरी को पास कर सकते हैं।

अपने दो stacktraces के बीच फर्क सिर्फ इतना स्पष्ट लैम्ब्डा के साथ एक इस लाइन है कि कहा:

at com.example.StackTractTest.lambda$0(StackTractTest.java:26) 

यह है, क्योंकि लैम्ब्डा एक नव उत्पन्न विधि में javac द्वारा अनुवाद किया गया था, और आप वास्तव में स्टैकट्रैक में देख सकते हैं कि यह नई विधि lambda$0 थी।

विधि-संदर्भ के साथ, एक नई विधि उत्पन्न करना आवश्यक नहीं है क्योंकि यह सीधे एक मौजूदा विधि का संदर्भ देता है।

2

नहीं - वास्तव में आपको अधिक स्पष्टता मिलती है।

तथ्य यह है कि at com.example.StackTractTest.lambda$0(StackTractTest.java:26) लाइन लैम्ब्डा संस्करण में दिखाई देता आपको याद दिलाता है एक लैम्ब्डा एक विधि संदर्भ का उपयोग करते समय कुछ भी अतिरिक्त पैदा नहीं करता इस तकनीक के लिए बनाई गई है।

लैम्ब्डा रन-टाइम पर बनाया गया है, विधि-संदर्भ संकलन समय पर बनाया जा सकता है।

+2

धन्यवाद लेकिन मुझे यकीन नहीं है कि मैं सहमत हूं कि आपको और स्पष्टता मिलती है।जबकि स्टैक ट्रेस सटीक रूप से प्रतिनिधित्व करता है कि क्या हो रहा है, लैम्ब्डा संस्करण का उपयोग उस बिंदु की पहचान करने का व्यावहारिक लाभ है जिस पर त्रुटि हुई। यह जानकारी विधि संदर्भों के लिए उपलब्ध नहीं दिखती है। यदि एक विधि संदर्भ एक पाइपलाइन में एक से अधिक बार प्रकट होता है, यह जानकर कि किस उदाहरण ने रनटाइम अपवाद को ट्रिगर किया हो, उपयोगी हो सकता है। – henry

+2

लेकिन यह वह बिंदु नहीं है जिस पर त्रुटि हुई। समय-समय-निर्माण लैम्ब्डा या विधि संभाल के लिए उपयोग के समय के समान नहीं है। एक थंब पूल में एक लैम्ब्डा जमा करने की कल्पना करो। त्रुटि तब बाद में होगी जब लैम्ब्डा जारी करने वाली विधि पहले ही निकल चुकी है। आप मूल रूप से कॉल-साइट के बजाय आवंटन साइट के बारे में पूछ रहे हैं, सूचना स्टैक निशान पारंपरिक रूप से शामिल नहीं होते हैं। यह पूछने की तरह होगा "थ्रेडपूल में प्रस्तुत किए गए रननेबल को आवंटित किया गया है"। – the8472

संबंधित मुद्दे