2008-10-27 11 views
14

मैं एक लाइब्रेरी में परिभाषित कक्षा को विस्तारित कर रहा हूं जिसे मैं नहीं बदल सकता:कच्चे प्रकार के पैरामीटर के साथ एक विधि को ओवरराइड करते समय अनचेक चेतावनी से बचा जा सकता है?

public class Parent 
{ 
    public void init(Map properties) { ... } 
} 

अगर मैं कक्षा 'चाइल्ड' को परिभाषित कर रहा हूं जो माता-पिता को बढ़ाता है और मैं जेनिक्स के साथ जावा 6 का उपयोग कर रहा हूं, तो ओवरराइड करने का सबसे अच्छा तरीका क्या है अनचाहे चेतावनी के बिना init विधि?

public class Child extends Parent 
{ 
    // warning: Map is a raw type. References to generic type Map<K,V> should be parameterized 
    public void init(Map properties) { } 
} 

यदि मैं जेनेरिक पैरामीटर जोड़ता हूं, तो मुझे मिलता है:

 // error: The method init(Map<Object,Object>) of type Child has the same erasure as init(Map) of type Parent but does not override it 
    public void init(Map<Object,Object>) { ... } 
    // same error 
    public void init(Map<? extends Object,? extends Object>) { ... } 
    // same error 
    public void init(Map<?,?>) { ... } 

यह त्रुटि इस बात पर ध्यान दिए बिना कि मैं एक विशिष्ट प्रकार, एक बाध्य वाइल्डकार्ड, या एक असंबद्ध वाइल्डकार्ड का उपयोग करता हूं। क्या चेतावनी के बिना गैर-जेनेरिक विधि को ओवरराइड करने के लिए कोई सही या बेवकूफ तरीका है, और @SuppressWarnings ("अनचेक") का उपयोग किए बिना?

उत्तर

12

हाँ, आप, माता पिता के वर्ग में के समान हस्ताक्षर से अधिभावी प्रणाली की घोषणा के लिए किसी भी जेनरिक जानकारी जोड़ने के बिना है।

मुझे लगता है कि आपका सर्वश्रेष्ठ दांव करने के लिए है कच्चे प्रकार के पैरामीटर के लिए @SuppressWarnings("unchecked") एनोटेशन जोड़ें, विधि नहीं, इसलिए आप अपने जेनरेट चेतावनियों को अपने कोड में नहीं डाल पाएंगे।

+0

@SuppressWarnings निश्चित रूप से यहां आपकी सबसे अच्छी शर्त है। बेकार है, लेकिन ऐसा तब होता है जब आप जेनेरिक को लाइब्रेरी में मजबूर करने का प्रयास करते हैं जो उनका उपयोग नहीं करता है। –

+0

'@SuppressWarnings (" rawtypes ")' भी पर्याप्त होना चाहिए। –

2

संक्षिप्त उत्तर: ऐसा करने का कोई तरीका नहीं है।

असंतुष्ट उत्तर: अपने आईडीई/build.xml में (विशिष्ट) चेतावनियों को अक्षम करें।

यदि आप लाइब्रेरी को नहीं बदल सकते हैं, तो आपको गैर-सामान्य तरीकों से चिपकना होगा।

समस्या यह है कि, बाद में मिटाए जाने के बावजूद दोनों init() में एक ही हस्ताक्षर है, वे वास्तव में विभिन्न तरीकों से हो सकते हैं - या वही (*)। कंपाइलर यह नहीं बता सकता कि यह ओवरराइड या अधिभारित करना चाहिए, इसलिए यह निषिद्ध है।

(*) मान लीजिए लाइब्रेरी डेवलपर का मतलब init (मानचित्र < स्ट्रिंग, इंटीजर >)। अब आप init लागू कर रहे हैं (मानचित्र < स्ट्रिंग, स्ट्रिंग >)। यह ओवरलोडिंग है, और बाल वर्ग के vtable में दो विधियां मौजूद होनी चाहिए।

लेकिन लाइब्रेरी डेवलपर का मतलब init (मानचित्र < स्ट्रिंग, स्ट्रिंग >) क्या होगा? फिर यह ओवरराइडिंग हो रहा है, और आपकी विधि बाल कक्षा में मूल init को प्रतिस्थापित करनी चाहिए, और बच्चे के vtable में केवल एक ही विधि होगी।

पीएस मुझे नफरत है कैसे जेनेरिक्स

:-(जावा में लागू
+0

क्या आप कृपया बता सकते हैं कि एक ही (मिटाए गए) हस्ताक्षर के साथ विधियां संकलक के लिए अलग-अलग तरीके क्यों हो सकती हैं? कंपाइलर नहीं जानता कि डेवलपर _meant_ कोडिंग करते समय ... ;-) – nrainer

0

आपको पैरेंट के समान हस्ताक्षर के साथ विधि घोषित करना है, और इसलिए जब आप संकलित करते हैं तो आपको चेतावनियां मिलेंगी। आप उन्हें @SuppressWarnings ("अनचेक") से दबा सकते हैं

इसका कारण यह है कि इससे छुटकारा पाने का कोई तरीका नहीं है कि चेतावनियां आपको यह बताने के लिए हैं कि उनमें अमान्य प्रकार के साथ संग्रह बनाना संभव है। चेतावनियों को केवल तभी जाना चाहिए जब सभी कोड जो इसे हटाए जा सकें। चूंकि आप एक गैर-जेनेरिक वर्ग से विरासत में हैं, इसलिए अमान्य सामग्री के साथ संग्रह बनाना हमेशा संभव होगा।

2

मुझे लगता है कि उत्तर के ऊपर @SuppressWarnings ("rawtypes") कहने के लिए उत्तर दिया गया है।

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

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