2015-06-10 7 views
13

का जिक्र: Wildcard Capture Helper Methodsजंगली कार्ड कैप्चर सहायक विधि का उपयोग क्यों करें?

यह जंगली कार्ड को पकड़ने के लिए एक सहायक विधि बनाने के लिए कहता है।

public void foo(List<?> i) { 
    fooHelper(i); 
}   
private <T> void fooHelper(List<T> l) { 
    l.set(0, l.get(0)); 
} 

बस अकेले नीचे इस फ़ंक्शन का उपयोग करने से कोई संकलन त्रुटियां उत्पन्न नहीं होती हैं, और ऐसा ही काम करता है। जो मुझे समझ में नहीं आता है वह है: आप इसका उपयोग क्यों नहीं करेंगे और एक सहायक का उपयोग करने से बचें?

public <T> void foo(List<T> l) { 
    l.set(0, l.get(0)); 
} 

मैंने सोचा कि यह प्रश्न वास्तव में उबाल जाएगा: वाइल्डकार्ड और जेनेरिक के बीच क्या अंतर है? तो, मैं इस पर गया: difference between wildcard and generics

1) If you want to enforce some relationship on the different types of method arguments, you can't do that with wildcards, you have to use type parameters.

वास्तव में क्या सहायक समारोह के साथ वाइल्डकार्ड वास्तव में क्या कर रहा है नहीं लेकिन, वह है: यह प्रकार पैरामीटर का उपयोग करने का कहना है? क्या यह अपनी सेटिंग और अज्ञात मूल्यों के साथ विभिन्न प्रकार के विधि तर्कों पर रिश्ते को लागू नहीं कर रहा है?

मेरा प्रश्न है: यदि आपको कुछ ऐसी परिभाषित करना है जिसके लिए विभिन्न प्रकार के विधि तर्कों पर रिश्ते की आवश्यकता है, तो पहले जगह में वाइल्डकार्ड का उपयोग क्यों करें और उसके बाद एक सहायक कार्य का उपयोग करें?

यह वाइल्डकार्ड को शामिल करने के लिए एक हैकी तरीका जैसा प्रतीत होता है।

+1

नहीं, यह पहले से ही –

उत्तर

7

इस विशेष मामले में ऐसा इसलिए है क्योंकि List.set(int, E) विधि को प्रकार में सूची के प्रकार के समान होना आवश्यक है। सहायक विधि के साथ

The method set(int, capture#1-of ?) in the type List<capture#1-of ?> is not applicable for the arguments (int, capture#2-of ?) 

:

आप सहायक विधि नहीं है, तो, संकलक अगर ?List<?> लिए एक ही है और get(int) से वापसी तो आप एक संकलक त्रुटि मिलती है पता नहीं है , आप कंपाइलर को बता रहे हैं, प्रकार वही है, मुझे नहीं पता कि यह किस प्रकार है।

तो गैर-सहायक विधि क्यों है?

जेनिक्स जावा 5 तक पेश नहीं किए गए थे, इसलिए वहां बहुत सारे कोड हैं जो जेनेरिकों की भविष्यवाणी करते हैं। एक प्री-जावा 5 List अब List<?> है, इसलिए यदि आप एक सामान्य जागरूक कंपाइलर में पुराने कोड को संकलित करने का प्रयास कर रहे थे, तो यदि आप विधि हस्ताक्षर नहीं बदल पा रहे हैं तो आपको इन सहायक विधियों को जोड़ना होगा।

+1

पर नहीं देखा गया है, लेकिन यदि आप वाइल्डकार्ड फ़ंक्शन को अनदेखा करते हैं, और केवल सहायक का उपयोग करते हैं तो भी आप किसी भी संकलन त्रुटियों के बिना सही आउटपुट प्राप्त कर सकते हैं। –

+0

@ ब्रैंडनलिंग हाँ यह सच है, मैं अपना जवाब अपडेट करूंगा। – dkatzel

+0

मैं समझता हूं कि क्यों संकलक सहायक कार्य के बिना वाइल्डकार्ड को समझ में नहीं आता है, लेकिन पूर्व जावा 5 भाग ने मेरे प्रश्न का उत्तर दिया। धन्यवाद। –

2

मैं सहमत हूं: सहायक विधि हटाएं और सार्वजनिक API टाइप करें। इसके लिए कोई कारण नहीं है, और हर कारण है।

बस वाइल्डकार्ड संस्करण के साथ सहायक के लिए की जरूरत संक्षेप में प्रस्तुत करने: यद्यपि यह मनुष्य के रूप में हमारे लिए स्पष्ट है, संकलक नहीं जानता है कि अज्ञात प्रकार l.get(0) से लौटे सूची ही की ही अज्ञात प्रकार है। यानी यह कारक नहीं है कि set() कॉल का पैरामीटर उसी सूची वस्तु से लक्ष्य के रूप में आता है, इसलिए यह एक सुरक्षित संचालन होना चाहिए। यह केवल नोटिस करता है कि get() से लौटाया गया प्रकार अज्ञात है और लक्ष्य सूची का प्रकार अज्ञात है, और दो अज्ञात एक ही प्रकार के होने की गारंटी नहीं है।

4

आप सही हैं कि हमें वाइल्डकार्ड संस्करण का उपयोग करने की आवश्यकता नहीं है।

यह नीचे आता है जो करने के लिए एपीआई/"बेहतर" लगता है लग रहा है, जो व्यक्तिपरक

void foo(List<?> i) 
<T> void foo(List<T> i) 

है मैं कहूँगा 1 संस्करण बेहतर है।

अगर कोई सीमा नहीं

void foo(List<? extends Number> i) 
<T extends Number> void foo(List<T> i) 

1 संस्करण भी अधिक कॉम्पैक्ट लग रहा है कर रहे हैं; प्रकार की जानकारी सभी एक ही स्थान पर हैं।

इस समय, वाइल्डकार्ड संस्करण बेवकूफ तरीका है, और यह प्रोग्रामर से अधिक परिचित है।

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

+2

@SotiriosDelimanolis - मुझे प्रश्न से अलग पढ़ना पड़ा - ओपी पूछता है कि '' संस्करण का बिंदु क्या है जबकि '' संस्करण ठीक काम करता है। – ZhongYu

+1

ओपी जानता है कि '' कॉलर की तरफ से काम करता है; लेकिन कार्यान्वयनकर्ता के पक्ष को ' 'सहायक की आवश्यकता होती है। ओपी '' संस्करण को एक अनावश्यक मध्यस्थ मानता है, पूछता है कि हम अभी ' 'संस्करण का खुलासा क्यों नहीं करते हैं। – ZhongYu

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