------------ अंतिम अद्यतन ---------

मुझे लगता है कि शायद List<?> और List<E> एक ही प्रकार के हैं जब हम उन्हें एक विधि तर्क के रूप में घोषित करते हैं। मैंने List<E> को List<?> में बदलने की कोशिश की, इसने भी ठीक काम किया:

public static <E> void swap2(List<E> list, int i, int j){
    swapHelper2(list, i ,j);
}

private static void swapHelper2(List<?> list, int i, int j) {
    ...
}

------------ मूल प्रश्न ------------

प्रभावी जावा》 आइटम ३१ से यह कहता है:

वाइल्डकार्ड प्रकार को कैप्चर करने के लिए एक निजी सहायक विधि लिखने का विचार है ...

'निजी सहायक विधि':

public static void swap(List<?> list, int i, int j) {
    swapHelper(list, i, j);
}
// Private helper method for wildcard capture
private static <E> void swapHelper(List<E> list, int i, int j) { 
    list.set(i, list.set(j, list.get(i)));
}

मेरा सवाल यह है कि क्यों सूची संकलन त्रुटि के बिना विधि आमंत्रण के माध्यम से सूची <ई> में परिवर्तित हो सकती है?

मेरी राय में मुझे लगता है कि List किसी भी List का सुपरटाइप है, इसलिए इसे कुछ संकुचित रूपांतरण की आवश्यकता होनी चाहिए जैसे:

List<?> list = new ArrayList<>();
List<String> listOfString = (List<String>)list;
swapHelper(listOfString, 0 ,0);
4
helpmeRein 3 सितंबर 2021, 16:23

2 जवाब

सबसे बढ़िया उत्तर

List<?> वास्तव में क्या दर्शाता है? इसका अर्थ है "एक सूची जिसमें कुछ अज्ञात प्रकार की वस्तुएं हैं"।

जब एक प्रकार तर्क <E> आपके swapHelper के रूप में होता है, तो कोई विधि क्या कहती है? यह कहता है: मैं किसी भी मनमानी प्रकार E को स्वीकार करता हूं।

हम जानते हैं कि ऊपर दिया गया ? कुछ प्रकार का है, हम नहीं जानते कि कौन सा है। <E> कोई भी प्रकार स्वीकार करता है, इसलिए हम जानते हैं कि जो भी ? उसका प्रतिनिधित्व करता है, उसे E के रूप में इस्तेमाल किया जा सकता है। इसलिए आप swapHelper को List<?> से कॉल कर सकते हैं।

हम एक List<?> वेरिएबल को List<E> वेरिएबल में निर्दिष्ट करके वह चाल क्यों नहीं कर सकते? चूंकि एक स्थानीय चर में प्रकार के तर्क नहीं होते हैं, वे केवल विधियों और वर्गों पर मौजूद होते हैं।

तो तथ्य यह है कि swapHelper में अप्रतिबंधित प्रकार चर है, यह List<?> को कभी भी "जानने" के बिना कोड में कुछ भी स्वीकार करने में सक्षम बनाता है कि ? वास्तव में क्या दर्शाता है, क्योंकि यह केवल परवाह करता है कि वहां है एक प्रकार है, न कि क्या वह प्रकार है।

4
Joachim Sauer 3 सितंबर 2021, 13:27

List<?> का अर्थ है "एक सूची जिसका तत्व प्रकार यहां ज्ञात नहीं है"।

यह कहना नहीं है कि तत्व प्रकार बिल्कुल भी ज्ञात नहीं है, बस, कोड में इस बिंदु पर, आप नहीं जानते कि यह क्या है।

लेकिन सभी List के पास कुछ तत्व प्रकार हैं (जब तक कि वे कच्चे न हों, मुझे लगता है)। तो, एक List<?> में कुछ तत्व प्रकार होते हैं, यदि केवल आप जानते हैं कि यह क्या था।

जब आप List<E> कहते हैं, तब भी आप वास्तव में नहीं जानते कि तत्व किस प्रकार का है। आप जानते हैं कि यह Object का उप-प्रकार है, लेकिन इससे अधिक कुछ नहीं। हालांकि, महत्वपूर्ण रूप से, आप जानते हैं कि यदि आपको List<E> से कोई तत्व मिलता है, तो यह एक प्रकार की E है:

E item = list.get(i);

और आप जानते हैं कि उस चीज़ को वापस सूची में रखना सुरक्षित होगा:

list.set(j, item);

आप नहीं जानते कि E किस प्रकार का है - लेकिन आप जानते हैं कि यह सूची के तत्वों के समान प्रकार है।

इसलिए, आप हमेशा एक List<?> को एक सामान्य विधि में पास कर सकते हैं (अर्थात, यह अपने प्रकार के चर घोषित करता है) जो List<E> की अपेक्षा करता है, क्योंकि आप कह रहे हैं कि तत्वों का एक सुसंगत प्रकार होता है, भले ही आप नहीं जानते कि यह क्या है।

4
Andy Turner 3 सितंबर 2021, 13:33