2013-10-02 7 views
9

के साथ अपरिवर्तनीय मैप बनाने का मुद्दा मैं ImmutableMap बनाने की कोशिश कर रहा हूं जो तारों को कक्षाओं में मैप करता है (नोट: यह निश्चित रूप से केवल एक उदाहरण है!)। हालांकि, जैसेकक्षा <?> कुंजी

ImmutableMap<Class<?>, String> map = ImmutableMap.of( 
    Integer.class, "Integer", 
    Date.class, "Date" 
); 

कुछ मुझे निम्न त्रुटि

Type mismatch: cannot convert from ImmutableMap<Class<? extends Object&Comparable<?>&Serializable>,String> to ImmutableMap<Class<?>,String> 

अजीब तरह से पर्याप्त अगर मैं कुंजी के किसी भी (!) के लिए Class<?> करने के लिए एक वर्णक जोड़ने के काम करता है, यानी

ImmutableMap<Class<?>, String> map = ImmutableMap.of(
    Integer.class, "Integer", 
    Date.class, "Date", 
    (Class<?>) String.class, "String", 
    long.class, "Long" 
); 
देता है

ठीक काम करेगा। मैं इस व्यवहार से परेशान हूं: एक के लिए, यह बिना जानवरों के काम क्यों करता है? ये सभी कक्षाएं हैं और यह वास्तव में Class<?> से अधिक सामान्य नहीं है, तो यह क्यों काम नहीं करता है? दूसरा, चाबियों में से किसी एक पर कास्ट क्यों काम करता है?

(ओर ध्यान दें: अगर आप सोच रहे हैं क्यों मैं भी ऐसा करना चाहते हैं - हाँ, यह प्रतिबिंब की वजह से है ...)

संपादित करें: मैं वास्तव में सिर्फ पता लगा है कि इस काम करेंगे, लेकिन मैं stil ऊपर व्यवहार

ImmutableMap<Class<?>, String> map = ImmutableMap.<Class<?>, String>builder() 
    .put(Integer.class, "Integer") 
    .put(Date.class, "Date") 
    .build(); 

उत्तर

15

यह कैसे संकलक प्रकार पैरामीटर infers जब आप असंगत विधि तर्क पारित है समझने के लिए चाहते हैं। यदि आप देखते हैं, ImmutableMap.of(K, V, K, V) विधि Date और Integer दोनों के लिए समान प्रकार पैरामीटर K का उपयोग करता है। कोई सोचता है कि यह विफल होना चाहिए क्योंकि हम असंगत विधि तर्क पारित कर रहे हैं, इसका मतलब है कि हम एक ही प्रकार के पैरामीटर K के लिए अलग-अलग प्रकार गुजर रहे हैं। लेकिन आश्चर्य की बात यह नहीं है।

  • Class<? extends Object>
  • Class<? extends Serializable>
  • Class<? extends Comparable<?>>

तो, प्रकार K सभी का एक मिश्रण के रूप में मान लिया जाता है:

Class<Date> और Class<Integer> निम्न में से सभी के लिए कब्जा परिवर्तनीय हैं:

K := Class<? extends Object&Serializable&Comparable<?>> 

है कि विधि के रिटर्न मान वास्तव में होगा:

ImmutableMap<Class<? extends Object&Serializable&Comparable<?>>, String> 
बेशक

, आप ImmutableMap<Class<?>, String> पर सीधे असाइन नहीं कर सकते, क्योंकि वे असंगत प्रकार हैं। यह भी ध्यान रखें कि, आप अपने मानचित्र को ऊपर के रूप में स्पष्ट रूप से घोषित नहीं कर सकते हैं, क्योंकि आप वाइल्डकार्ड के लिए कई सीमाएं नहीं दे सकते हैं। यह बस संकलक प्रकार का अनुमान लगाता है।

स्थिति है, जहां संकलक सही ढंग से टाइप तर्क अनुमान नहीं लगा सकता के रूप में आप की आवश्यकता की इन प्रकार के लिए, आप स्पष्ट प्रकार तर्क पारित कर सकते हैं, जो है, जबकि विधि मंगलाचरण, क्या आप अपने पिछले कोशिश में किया था:

ImmutableMap<Class<?>, String> map = ImmutableMap.<Class<?>, String>of( 
    Integer.class, "Integer", 
    Date.class, "Date" 
); 

अब यह काम करेगा, संकलक के रूप में स्पष्ट प्रकार तर्क से जानता है कि वापसी मान प्रकार का हो सकता है - ImmutableMap<Class<?>, String>

अजीब तरह से पर्याप्त यह d ओ इ एस कुंजी

की अगर मैं किसी भी करने के लिए Class<?> करने के लिए एक वर्णक जोड़ने के काम (!) जैसे ही आप Class<?> के तत्व के किसी भी डाली, क्योंकि Class<?> अर्थ है परिवार सब सब Class<T> के उदाहरण के रूप में टाइप करें, और इसलिए यह सभी Class उदाहरणों के लिए सामान्य सुपरटेप है। इसलिए, प्रकार तर्क को स्वचालित रूप से Class<?> के रूप में अनुमानित किया जाएगा। और यह ठीक काम करेगा।

+0

बहुत बढ़िया। धन्यवाद! –

+0

@ IngoBürk आपका स्वागत है :) –

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