/ / Instantiating जेनिक्स: नई ArrayList <?> () बनाम नई ArrayList <सूची <? >> () [डुप्लिकेट] - जावा, जेनेरिक

Instantiating जेनिक्स: नई ArrayList <?> () बनाम नई ArrayList <सूची <? >> () [डुप्लिकेट] - जावा, जेनेरिक

इसकी अनुमति क्यों है:

List<List<?>> list = new ArrayList<List<?>>()

लेकिन यह नहीं?

List<?> list = new ArrayList<?>(); //Compile error: "Cannot instantiate the type ArrayList<?>"

उत्तर:

जवाब के लिए 3 № 1

जब आप एक ArrayList बनाते हैं, तो आपको उस ऑब्जेक्ट के प्रकार को परिभाषित करने की आवश्यकता होती है जिसमें यह शामिल होगा:

  • पहले उदाहरण में, आप एक ऐरेलिस्ट बनाते हैं जिसमें अज्ञात सामान्य प्रकार की सूचियां होंगी, लेकिन वे सभी सूचीबद्ध होंगी।
  • दूसरे उदाहरण में, आप अज्ञात प्रकार के एक ArrayList बनाने की कोशिश करते हैं, जिसकी अनुमति नहीं है।

उत्तर № 2 के लिए 1

आप एक अज्ञात जेनेरिक के साथ किसी ऑब्जेक्ट को तुरंत चालू नहीं कर सकते हैं, यही कारण है कि दूसरी पंक्ति विफल हो जाती है।

List<?> list = new ArrayList<String>();

हालांकि "सूची" का उपयोग करते समय काम करेंगे, कोड यह नहीं जानता कि यह एक स्ट्रिंग सूची थी जो इसे बेकार बना रही थी।

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


जवाब के लिए 0 № 3

दोनों के रूप में एक सामान्य प्रकार परिभाषा के बारे में सोचो

  1. एक सामान्य प्रकार का एक नया गैर-जेनेरिक "प्रकार उदाहरण" बनाने में सक्षम होने के लिए कुछ प्रकार के कन्स्ट्रक्टर की परिभाषा।
  2. एक प्रकार की परिभाषा।

अब इस तर्क को गैर-जेनेरिक चरों में अनुवाद करने दें:

CharSequence val = new String("foo");

पूरी तरह से कानूनी है। चर val प्रतिनिधित्व कर रहा है एक प्रकार (2) और निश्चित रूप से इंटरफेस के प्रत्यक्ष उदाहरण कभी नहीं होंगे CharSequence। हालांकि आप नहीं कर सकते थे निर्माण (1) इस प्रकार, लेकिन आप इसे असाइन करने योग्य उप प्रकार निर्दिष्ट कर सकते हैं जैसे कि ए String। आप न तो कुछ बताकर स्ट्रिंग के निर्माण को प्रतिस्थापित कर सकते हैं new [? extends CharSequence], आपको उस प्रकार का नाम स्पष्ट रूप से नामित करने की आवश्यकता है।

अब जेनिक्स पर वापस जाएं जहां चीजें समान हैं। जब आप एक सामान्य प्रकार के कन्स्ट्रक्टर को कॉल करते हैं।

new ArrayList<List<?>>()

आप एक तरह से हैं निर्माण (2) एक सामान्य प्रकार का एक नया "प्रकार उदाहरण" जहां आपको टाइप वैरिएबल को एक मान निर्दिष्ट करने की आवश्यकता है T में सामान्य परिभाषा का ArrayList<T>. ? अपने आप जावा प्रकार का वर्णन नहीं कर रहा है और इसलिए इसे असाइनमेंट मान के रूप में उपयोग नहीं किया जा सकता है। हालांकि, इसके अलावा T = ?, परिभाषा T = List<?> संभव है क्योंकि वाइल्डकार्ड वैध जावा प्रकार परिभाषा का हिस्सा हो सकता है।

एक में वाइल्डकार्ड का उपयोग करते समय प्रकार परिभाषा (1) के रूप में

List<?> list

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