2015-06-06 5 views
24

जावा 7 की रिलीज के साथ MethodHandle आया, जो उपयोगकर्ता को इसके अंतर्निहित बाइटकोड का उपयोग करने के तरीके की तरह एक विधि का आह्वान करने की अनुमति देता है।जब मेथडहैंडल तेज होता है तो क्लास सदस्यों तक पहुंचने के लिए प्रतिबिंब का उपयोग क्यों करें?

एक लुक वस्तु पर कारखाने तरीकों के लिए विधियों, कंस्ट्रक्टर्स, और खेतों सभी प्रमुख उपयोग के मामलों के अनुरूप: विशेष रूप से, MethodHandles.Lookup वर्ग कारखाने तरीकों बनाने के लिए विधि वर्ग के सदस्यों तक पहुँचने के लिए संभालती है प्रदान करता है। फ़ैक्टरी विधि द्वारा बनाए गए प्रत्येक विधि हैंडल एक विशेष बाइटकोड व्यवहार के कार्यात्मक समकक्ष है।

कार्यात्मक रूप से, यह इन वर्ग वर्ग सदस्यों तक पहुंचने के लिए प्रतिबिंब का उपयोग करने के बराबर या कम समकक्ष है, फिर भी method handles are faster than reflection

तो, क्या अभी भी Field#get(..)/Method.invoke(..) जैसे प्रतिबिंब कार्यक्षमताओं का उपयोग करने का कोई कारण है या क्या ये विधियां तेजी से विधि हैंडल की शुरुआत के साथ अप्रचलित हैं?

ध्यान दें कि जावा 7 में विधि हैंडल पेश किए जाने पर, मेरा प्रश्न मुख्य रूप से जावा 8 से संबंधित है, जिसमें उन्हें अनुमानित रूप से प्रत्यक्ष क्षेत्र/विधि कॉल के बराबर प्रदर्शन तक पहुंचने के लिए ऑप्टिमाइज़ किया गया था, प्रतिबिंब की क्षमता को पार करते हुए।

+0

विधि हैंडल पर अधिक जानकारी के लिए, [MethodHandle - यह सब क्या है?] (Http: // stackoverflow देखें।कॉम/क्यू/88237 9 3/1247781) – Vulcan

+0

यह बहुत तेजी से नहीं दिखता है, खासकर अगर आप प्रतिबिंब में पहुंच जांच बंद कर देते हैं ('सेट असफल (सत्य) ' – ZhongYu

+0

@ bayou.io यह उचित लगता है, लेकिन क्या आपके पास कोई बेंचमार्क परीक्षण है साक्ष्य के रूप में? 'सेटएक्सेबल (सत्य)' को कॉल करने के लिए लिंक किए गए प्रश्न में बस बेंचमार्क को संशोधित करना और उन परिणामों को आउटपुट करना मेरे लिए पर्याप्त सबूत होगा। – Vulcan

उत्तर

22

प्रतिबिंब और विधि हैंडल विभिन्न उद्देश्यों की पूर्ति करते हैं, और अमूर्तता के विभिन्न स्तरों पर मौजूद हैं। आपको उस समस्या का उपयोग करना चाहिए जो आपके द्वारा हल की जा रही समस्या के लिए सही है।

प्रतिबिंब एक सामान्य उद्देश्य आत्मनिरीक्षण तंत्र है, जिसमें एक विधि (Class.getMethods()) के सदस्यों की गणना करने जैसे विधि संभाल तंत्र की कमी है, जिसमें सदस्य की विशेषताओं का निरीक्षण करना जैसे कि इसकी पहुंच-योग्यता झंडे, जेनेरिक का निरीक्षण करना सदस्यों के हस्ताक्षर, आदि

इसके अतिरिक्त, प्रतिबिंबित वस्तुओं को शारी तक पहुंच प्रदान किए बिना स्वतंत्र रूप से साझा किया जा सकता है, क्योंकि प्रत्येक आमंत्रण पर पहुंच जांच की जाती है; विधि हैंडल को आह्वान करने की क्षमता को प्रदान करता है। इसलिए उनके पास विभिन्न सुरक्षा प्रभाव भी हैं।

विधि हैंडल विधियों को खोजने, अनुकूलित करने और आविष्कार करने के लिए निम्न स्तर की तंत्र हैं। जबकि विधि हैंडल के माध्यम से आमंत्रण प्रतिबिंब के माध्यम से तेज़ है (हालांकि आज तक, प्रत्यक्ष बाइटकोड आमंत्रण अभी भी विधि हैंडल आमंत्रण की तुलना में आम तौर पर तेज़ है), विधि हैंडल का उपयोग करने में भी काफी कठिन होता है, क्योंकि वे स्वचालित रूप से अनुकूलन नहीं करते हैं जो जावा उपयोगकर्ता अपेक्षा करते हैं (जैसे कि स्ट्रिंग तर्क को ऑब्जेक्ट में कनवर्ट करना), जिसके परिणामस्वरूप लिंक त्रुटियां होती हैं।

प्रतिबिंब पुस्तकालय मुख्यधारा के जावा उपयोगकर्ताओं के उद्देश्य से है; विधि हैंडल परत का उद्देश्य कंपाइलर और भाषा रनटाइम लेखकों पर अधिक है। नौकरी के लिए डिज़ाइन किया गया टूल चुनें।

+0

हालांकि यह उत्तर उपयोगी है, मेरा प्रश्न केवल 'फ़ील्ड # गेट/सेट'' के उपयोग से संबंधित है और वर्ग के सदस्यों को एक्सेस/आमंत्रित करने के लिए 'विधि # आवेदक' है, और क्या विधि के हैंडल करते समय इन प्रतिबिंब विधियों का उपयोग करने का कोई कारण है या नहीं समान पहुंच/आमंत्रण प्राप्त करने के लिए अनुमानित तेज़ तरीके प्रदान करें। – Vulcan

+10

प्रदर्शन किसी कार्य के लिए उपयुक्तता का एकमात्र उपाय नहीं है। विधि हैंडल तेज़ होते हैं, लेकिन वे कम लचीला और उपयोग करने में कठिन होते हैं। शायद विधि हैंडल आपकी समस्या के लिए सही उपकरण हैं (आपने वास्तव में इसे समझाया नहीं है), शायद वे नहीं हैं। लेकिन आपका सवाल था, "हमारे पास विधि हैंडल होने पर प्रतिबिंब का उपयोग क्यों करें"। और कई कारण हैं कि आप आमंत्रण प्रदर्शन के अलावा, प्रतिबिंब क्यों पसंद कर सकते हैं। –

5

tl; डॉ नहीं, जब आप कर सकते हैं कोर प्रतिबिंब एपीआई का उपयोग करना चाहिए (और पसंद करते हैं) MethodHandles

MethodHandles.Lookup access कहते हैं (आंशिक रूप से),

कोर प्रतिबिंब एपीआई, जहां पहुँच हर बार एक चिंतनशील विधि शुरू हो जाती है चेक किया गया है के साथ विपरीत, विधि संभाल पहुँच जाँच when the method handle is created किया जाता है।

+0

@BrianGoetz क्या आपको याद आया * मेरा प्रश्न मुख्य रूप से जावा 8 में उनके प्रदर्शन से संबंधित है, जिसमें उन्हें सीधे क्षेत्र/विधि कॉल * के बराबर प्रदर्शन तक पहुंचने के लिए अनुकूलित किया गया था? –

+2

"जावा ** में प्रदर्शन ** **", जावा 7 में प्रदर्शन के विपरीत, "मुख्य रूप से ... प्रदर्शन" नहीं। – zeroflagL

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

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