2009-05-31 9 views
8

तो मैं एक नक्शा है:जावा जेनेरिक्स कक्षा के साथ <T>

Map<String, Class> format = new HashMap<String, Class>(); 

और मैं इस तरह यह करने के लिए तत्वों को जोड़ने होगा:

format.put("Vendor Number", Integer.class); 
format.put("Vendor Dispatch", Date.class); 
.... 

मैं एक सामान्य विधि है इस प्रकार है:

public static <T> T verifyType(String name, Class<T> type) { 
    if (type == Integer.class) { 
     return type.cast(new Integer(Integer.parseInt(name))); 
    } 
      ...... 
    return null; 
} 

अब कोड का यह टुकड़ा कोई कंपाइलर समस्याओं के साथ काम करता है:

Integer i = verifyType("100",Integer.class); 

लेकिन, जब मैं कोशिश यह:

Integer i = verifyType("100",format.get("Vendor Number")); 

OR 

    Class type = Integer.class 
    Integer i = verifyType("100",type); 

संकलक मुझे इस चेतावनी दिखाता है: प्रकार की सुरक्षा: अनियंत्रित मंगलाचरण verifyType (स्ट्रिंग, क्लास) सामान्य विधि verifyType (स्ट्रिंग, क्लास)

की

छोड़ देता है जो मुझे हैरान ... कृपया मदद ...

उत्तर

8

बदलें:

Class type = Integer.class 
Integer i = verifyType("100",type); 

Class<Integer> type = Integer.class 
Integer i = verifyType("100",type); 

को केवल 'क्लास' के रूप में प्रकार की घोषणा, आप सामान्य पैरामीटर खो रहे हैं और verifyType() विधि वर्ग अनुमान नहीं लगा सकता तक , इस प्रकार अनचेक चेतावनी।

यह समस्या:

Map<String, Class> format = new HashMap<String, Class>(); 
format.put("Vendor Number", Integer.class); 
format.put("Vendor Dispatch", Date.class); 
Integer i = verifyType("100",format.get("Vendor Number")); 

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

+0

यह काम करता है, हालांकि, जाहिर है, अगर मैं घोषित हैशपैप से कक्षा प्राप्त करना चाहता हूं तो यह चेतावनी को दबाएगा। धुएं और दर्पण के लिए – Jay

+3

+1 –

2

यह क्योंकि आपके HashMap देता है एक

Class 

वस्तु, लेकिन यह सत्यापित समारोह एक

Class<T> 

वस्तु की उम्मीद है।

+0

अच्छी तरह से ... मैं इस यहाँ मेरे सवाल पूछ से पहले बाहर की कोशिश की थी: नक्शा <स्ट्रिंग, कक्षा > प्रारूप = नए HashMap <स्ट्रिंग, कक्षा >(); केवल संकलक द्वारा सूचित किया जाना चाहिए कि "टी को एक प्रकार के रूप में हल नहीं किया जा सकता"। – Jay

+1

@Jay, कक्षा के साथ समस्या यह है कि आपके पास एक निर्धारित पैरामीटर होना चाहिए। आप क्या चाहते हैं कक्षा है। – Yishai

+0

@Yishai - धन्यवाद, उसने ऐसा किया। हालांकि, संकलक verifyType विधि पर वापसी के बारे में शिकायत: (! मान = नल) \ N सार्वजनिक स्थिर टी verifyType (स्ट्रिंग मान, कक्षा प्रकार) \t \t \t फेंकता LKNException { यदि { \t \t \t अगर (प्रकार == Integer.class) { \t \t \t \t कोशिश { \t \t \t \t \t वापसी type.cast (नई पूर्णांक (मान)); \t \t \t \t} पकड़ें (अपवाद गलती) {} } – Jay

0

कक्षा Class एक सामान्य वर्ग है। यदि आप

Class<Integer> type = Integer.class; 
Integer i = verifyType("100", type); 

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

तुम भी चेतावनी कोड या विधि के विशिष्ट लाइन से पहले

@SuppressWarning("unchecked") 

का उपयोग कर दबाने से संकलक समझा सकते हैं।

1

आपको यह त्रुटि मिलने का कारण यह है कि पहले मामले में संकलक देखता है कि आप इसे क्लास ऑब्जेक्ट पास करते हैं और संकलन समय पर टी को इंटीजर से बांधने में सक्षम हैं, लेकिन दूसरे मामले में संकलक केवल देखता है कि आप हैं इसे कक्षा वस्तु पास कर रहा है।

दिन के अंत में, आप एक प्रकार सुरक्षित तरीके से

Integer i = verifyType("100",format.get("Vendor Number")); 

ऐसा करने में सक्षम नहीं होगा, के बाद से संकलक पता नहीं कर सकते हैं कि आप एक पूर्णांक (मिल जाएगा क्या अगर कोई करता है एक format.put सिर्फ इतना है कि कॉल करने से पहले ("विक्रेता संख्या", X.class)?)

4

आप कक्षा के लिए अपने संदर्भ genericize किया है। उदाहरण के लिए:

Class<Integer> type = Integer.class 
Integer i = verifyType("100",type); 

ठीक काम करेगा।

के रूप में होगा:

Map<String, Class<?>> format = new HashMap<String, Class<?>>(); 

बहरहाल, यह कभी काम नहीं करेगा:

Integer i = verifyType("100",format.get("Vendor Number")); 

क्योंकि प्रारूप निर्धारित नहीं है के रूप में:

Map<String, Class<Integer>> 

यदि ऐसा है तो कास्टिंग काम करेगा , लेकिन डिजाइन व्यर्थ होगा।

निकटतम आप प्राप्त कर सकते है:

Integer i = verifyType("100",(Class<Integer>) format.get("Vendor Number")); 

लेकिन, आप के रूप में आप चाहिए, यह कर एक संकलक चेतावनी मिल जाएगा - यह एक स्वाभाविक असुरक्षित ढला होता है। संकलक इसके लिए अपने शब्द ले जा रहा है कि कि format.get बयान एक पूर्णांक वापस आ जाएगी। आपको लगता है कि के बारे में सुनिश्चित कर रहे हैं, तो वह क्या असुरक्षित डाले के लिए कर रहे हैं। आप संकलक चेतावनी से छुटकारा पाने के लिए चाहते हैं, तो आप ऐसा कर सकते हैं:

Class<?> type = format.get("Vendor Number"); 
    Integer i = null; 
    if (type == Integer.class) { 
     i = verifyType("100", Integer.class); 
    } else { 
     //What do you want to do? 
    } 
+0

इंटीजर i = verifyType ("100", (कक्षा ) format.get ("विक्रेता संख्या")) के बजाय; आप लिख सकते हैं: इंटीजर i = (इंटीजर) सत्यापित टाइप ("100", format.get ("विक्रेता संख्या")); कम टाइपिंग। –

1

यह मेरे लिए अजीब है, कि लाइन

Integer i = verifyType("100",format.get("Vendor Number")); 

पर अपने संकलक अनियंत्रित मंगलाचरण के बारे में शिकायत लेकिन प्रदर्शित नहीं करता है एक त्रुटि जैसे "टाइप मिस्चैच: ऑब्जेक्ट से इंटीजर में कनवर्ट नहीं किया जा सकता"।

इस लाइन बस मेरे लिए कोई मतलब नहीं है। आप verifyType अगर यह एक दूसरा पैरामीटर के रूप में Date.class प्राप्त करता है वापस जाने के लिए क्या उम्मीद करते हैं? इसके अलावा एक इंटीजर (फिर सत्यापन प्रकार का रिटर्न प्रकार अमान्य है)? या एक तिथि? यदि आप एक तिथि आशा करते हैं, कैसे संकलक की उम्मीद है पता चला है कि

format.get("Vendor Number"); 

रिटर्न Integer.class, लेकिन

format.get("Vendor Dispatch"); 

रिटर्न Date.class

प्रार्थना की

Integer i = verifyType("100",format.get("Vendor Dispatch")); 

असफल होना चाहिए, क्योंकि तिथि एक पूर्णांक नहीं है।तो, मेरी राय में (और मेरे कंपाइलर की राय में) संकलन

Integer i = verifyType("100",format.get("Vendor Number")); 

विफल होना चाहिए।

+0

tkopec, मैं अलग होना चाहता हूँ। मुझे एहसास है कि मैं जो करने की कोशिश कर रहा हूं वह अलग-अलग प्रकार की वस्तुओं को सूची में जोड़ने से अलग नहीं है (जैसे जावा 1.4 में) - मुझे लगता है कि संकलक संकलन समय पर चेतावनी देगा (जो अभी यह कर रहा है), और रन टाइम पर कक्षा कास्ट अपवाद फेंक दें। संकलन पर असफल होने के लिए यह समझ में नहीं आता है। – Jay

+0

हू? यदि आप एक सादा सूची से तत्व लेते हैं, तो आपको इसे कास्ट करना होगा। आप इंटीजर i = list.get (0) लिख नहीं सकते; यह इंटीजर i = (पूर्णांक) list.get (0) होना चाहिए; आपका उदाहरण एक ही मामला है - संकलित करने के लिए यह इंटीजर i = (इंटीजर) सत्यापित प्रकार ("100", format.get ("विक्रेता संख्या") होना चाहिए; और चेतावनी परिवर्तन से छुटकारा पाने के लिए मानचित्र <स्ट्रिंग, कक्षा > प्रारूप = नया हैश मैप <स्ट्रिंग, कक्षा >(); –

+0

@tkopec बिंदु लिया गया। यदि मैं इसे कक्षा के रूप में घोषित करता हूं तो संकलक चेतावनियों को दबाता है। तो, मैं अपने सत्यापन प्रकार से क्या लौट सकता हूं (स्ट्रिंग वैल, कक्षा प्रकार> विधि? ऑब्जेक्ट ?? – Jay

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