हर बार जब मैं सोचता हूं मैं जेनरिक को बेहतर समझता हूं (और संकलन किए बिना उत्तर दे सकता हूं), मुझे एक उदाहरण मिलता है जहां यह सिद्धांत टूट जाता है। यहाँ एक बहुत ही सरल उदाहरण है:

static void consumer(List<? super List<String>> param) {
    System.out.println(param);
}

और दो आह्वान:

public static void main(String[] args) {
    List<String> list = List.of("123");
    consumer(list);
    consumer(List.of("123"));
}

मेरे लिए, किसी भी आमंत्रण को संकलित नहीं करना चाहिए। A String, List का सुपरटाइप नहीं है। फिर भी, दूसरा संकलित करता है। लेकिन मान लीजिए कि ऐसा इसलिए होता है क्योंकि कंपाइलर यहां कुछ टाइप का अनुमान लगा सकता है। बेशक ऐसा कोई प्रकार मौजूद नहीं है और यह रनटाइम पर विफल हो जाएगा, है ना? सही? नहीं। यह सिर्फ काम करता है। जैसे, क्या कोई कृपया मेरे जीवन में कुछ विवेक ला सकता है?

3
Eugene 23 अक्टूबर 2020, 06:50

2 जवाब

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

आह डर्न!

javac  --debug=verboseResolution=all Sandbox.java

दिखाता है कि consumer(List.of("123")) को संकलित किया गया है:

instantiated signature: (Object)List<Object>
target-type: List<? super List<String>>
9
Eugene 23 अक्टूबर 2020, 07:02

यदि आप अधिक "कार्यात्मक" स्पष्टीकरण चाहते हैं, तो आपको यह विचार करना होगा कि param क्या है।

PECS लागू करके, ध्यान दें कि यह एक सूची है जो कि List का उपभोक्ता है।

  • संगत उपभोक्ता वे हैं जो List<String> या इसके किसी मूल प्रकार का उपभोग कर सकते हैं;
  • जब List पर लागू किया जाता है, तो इसका मतलब एक सूची है जिस पर आप add() को किसी भी मूल प्रकार के List<String> से कॉल कर सकते हैं। इस प्रकार एक List<Object> संगत है।

यही कारण है कि consumer() को List<Object> के साथ बुलाया जा सकता है लेकिन List<String> के साथ नहीं (String List<String> का सुपरटाइप नहीं है)।

चूंकि List.of(…) हमेशा घोषणा के समय List<Object> से मेल खा सकता है, इसलिए यह दूसरी कॉल को स्वीकार करता है।

ध्यान दें कि consumer() विधि के अंदर से, आप कभी भी param से List<String> प्राप्त नहीं कर पाएंगे (अर्थात इसे एक निर्माता के रूप में उपयोग करें)। आप इसमें केवल नए जोड़ सकते हैं (यानी इसे उपभोक्ता के रूप में उपयोग करें) - और वास्तव में, आप List<String> को List<Object> में जोड़ सकते हैं (हालांकि इस विशेष मामले में, List.of() एक उत्पादन करता है अपरिवर्तनीय सूची, इसलिए यह रनटाइम पर विफल हो जाएगी)।

2
Didier L 29 अक्टूबर 2020, 15:37