2009-01-13 17 views
11

कैसे आते हैं, जावा में, मैं लिख सकते हैंजावा जेनरिक: सूची <Container<?>> = नया लिंक्डलिस्ट <कंटेनर <Double>>() निषिद्ध है?

List<?> list = new LinkedList<Double>(); 

नहीं बल्कि

List<Container<?>> list = new LinkedList<Container<Double>>(); 

जहां कंटेनर जैसे

public class Container<T> { ... } 

कुछ इस आया क्योंकि मैं एक विधि है कि स्वीकार करता है List<Container<?>>, और मैं Arrays.asList का उपयोग तर्कों को पास करने के लिए करना चाहता हूं:

process(Arrays.asList(new Container<Double>(), new Container<Double>())); 

लेकिन भाषा इस की अनुमति नहीं है, क्योंकि यह Arrays.asList के प्रकार infers List<Container<Double>> होने के लिए, और कहा कि List<Container<?>> को आबंटित नहीं है।

अगर मैं कॉल करने के लिए एक स्ट्रिंग-पैरामिट्रीकृत कंटेनर जोड़ने के लिए,

process(Arrays.asList(new Container<Double>(), new Container<String>())); 

यह अभी भी काम नहीं करता है, क्योंकि यह Arrays.asList के लिए प्रकार List<Container<? extends Serializable & Comparable<?>>> infers। केवल अगर मैं ऐसा कुछ करता हूं जो न तो तुलनात्मक है और न ही Serializable यह ठीक से काम करता है।

बेशक, मैं एक कलाकार डाल सकता हूं और संकलक को बंद करने के लिए प्राप्त कर सकता हूं, लेकिन मुझे आश्चर्य है कि मैं यहां कुछ गलत कर रहा हूं।

उत्तर

13

प्रत्येक parameterization में वाइल्डकार्ड किया जाना चाहिए:

List<? extends Container<?>> list = new LinkedList<Container<Double>>(); 

संपादित करें: मैं एक स्पष्टीकरण के लिए Angelika Langer's FAQ के माध्यम से खोज रहा था, लेकिन एक भी नहीं मिला (यह शायद वहाँ है, लेकिन 500 पृष्ठों में कहीं छुपा)।

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

2

संपादित करें: मैं एक स्पष्टीकरण के लिए एंजेलिका लैंगर के अक्सर पूछे जाने वाले प्रश्नों के माध्यम से खोज रहा था, लेकिन उसे कोई नहीं मिला (शायद यह वहां है, लेकिन 500 पृष्ठों में कहीं छिप रहा है)।

उत्तर के लिए बहुत बहुत धन्यवाद। मुझे एफएक्यू में स्पष्टीकरण मिला, और इसके बाद कुछ झुकाव के बाद मुझे लगता है कि मुझे यह मिल गया है।

http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeArguments.html#What%20do%20multilevel%20wildcards%20mean?

2

विचार करें कि क्या होगा यदि आप क्या कर सकते हैं।

List<Container<Double>> list1 = new LinkedList<Container<Double>>(); 
List<Container<?>> list2 = list1; // this shouldn't be allowed, because of the below 
Container<String> foo = new Container<String>(); 
foo.add("hi"); 
list2.add(foo); // legal, because Container<String> is a subtype of Container<?> 
Container<Double> bar = list1.get(0); 
Double x = bar.get(0); // type error; it is actually a String object 
         // this indicates that type safety was violated 
हालांकि

, List<? extends Container<?>> का उपयोग कर, क्योंकि आप कुछ भी नहीं डाल सकते (null को छोड़कर) इस प्रकार की एक सूची में इस समस्या नहीं है (कोई प्रकार है कि "? extends Container<?>" का एक उपप्रकार होने की गारंटी है क्योंकि वहाँ) ।

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