2009-01-16 21 views
8

मैं एक विरासत वर्ग उस वर्ग अपने आप में एक सामान्य लेकिन इसके तरीकों में से एक नहीं है में सामान्य वर्ग परिणामों के संदर्भ प्रकार जेनरिक का उपयोग करता है वापसी तारों का संग्रह वापस करने के लिए। इसलिए मैं getStuff() से अधिक पुनरावृति कर सकते हैं और एक String के तत्वों कास्ट करने के लिए कोई आवश्यकता नहीं है:गैर सामान्य गैर सामान्य वापसी प्रकार

Thing t = new Thing(); 
for (String s: t.getStuff()) // valid 
{ ... } 

हालांकि, अगर मैं Thing ही बदल एक सामान्य हो सकता है लेकिन सब कुछ और कुछ ही रखने के लिए:

public class Thing<T> { 
    public Collection<String> getStuff() { ... } 
} 

और फिर Thing, getStuff() पर गैर-जेनेरिक संदर्भ का उपयोग करते रहें अब Collection<String> लौटाता है और इसके बजाय एक गैर-टाइप Collection देता है। इस प्रकार क्लाइंट कोड संकलित नहीं करता है:

Thing t = new Thing(); 
for (String s: t.getStuff()) // compiler complains that Object can't be cast to String 
{ ... } 

यह क्यों है? कामकाज क्या हैं?

मेरा अनुमान है कि एक सामान्य वर्ग के गैर-जेनेरिक संदर्भ का उपयोग करके, जावा पूरे वर्ग के लिए सभी जेनेरिकों को बंद कर देता है। यह दर्द है, क्योंकि अब मैंने जेन को सामान्य बनाकर अपना क्लाइंट कोड तोड़ दिया है।

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

उत्तर

10

ठीक है, दो ले लो, मैंने आपके प्रश्न को गलत समझा।

जब आप delcare Thing (यह एक कच्चे प्रकार कहा जाता है) के बजाय Thing<?> (पैरामिट्रीकृत प्रकार) जावा कम्पाइलर बाहर स्ट्रिप्स सभी सामान्य तर्क, यहां तक ​​कि thogh (आपके मामले में) विधि के सामान्य प्रकार के वर्ग के सामान्य प्रकार के साथ कुछ लेना देना नहीं है।

(उत्कृष्ट) से Java Generics FAQ:

Can I use a raw type like any other type?

तरीके या एक कच्चे प्रकार के निर्माताओं के हस्ताक्षर है कि वे प्रकार विलोपन के बाद होता है।

यह प्रतीत होता है कि निर्दोष और अविभाज्य वाक्य प्रश्न में व्यवहार का वर्णन करता है। आप कच्चे प्रकार के रूप में Thing का उपयोग कर रहे हैं ताकि वापसी का प्रकार Collection (Collection<String> नहीं) क्योंकि यह प्रकार के बाद के प्रकार के बाद है।

उलझन में? आश्चर्य की बात नहीं। बस उस FAQ के आकार को देखें। पृथ्वी पर लगभग तीन लोग हैं जो जावा जेनरिक के पूर्ण प्रभाव को समझते हैं। बस जेडीके से मेरी पसंदीदा घोषणा पर विचार करें:

Enum<T extends Enum<T>> 

(एफएक्यू में भी इसका स्पष्टीकरण दिया गया है)।

+0

मैं किसी अन्य विधि (मेरे उदाहरण में सूचीबद्ध नहीं) के कारण जेन सामान्य बना रहा हूं। –

+0

यदि चीज चीज है (और बात नहीं है), तो यह संकलित नहीं होगा। आगे बढिए और इसे आजमाइए। –

+0

प्रश्न को गलत समझा, बदल गया। – cletus

0

यह मिटाने के कारण विफल रहा है।आप इन Java Tutorials

0

में इसके बारे में अधिक पढ़ सकते हैं, मुझे लगता है कि यह पूरी तरह से सामान्य है। थिंग टी = नई चीज() का उपयोग करके मेरी राय में; सामान्य सक्षम वर्ग के लिए पूरी तरह से एक गलती है। जब कंपाइलर बिना किसी पैरामीटर के कक्षा के रूप में उपयोग की जाने वाली जेनेरिक क्लास देखते हैं, तो ऐसा लगता है कि इसे उस वर्ग से सभी सामान्य प्रकारों को मिटाना होगा। इस प्रकार आप नए जावा कंपाइलर्स में जेनरिक के उपयोग के बिना पुराने कोड संकलित कर सकते हैं और कंपाइलर पुराने कोड सक्षम जेनरिक सक्षम वर्गों (जैसे java.util.ArrayList) किसी भी समस्या के बिना उपयोग करते हैं। (और इस प्रकार जावा को अलग सिस्टम की आवश्यकता नहीं है। चयन। जेनेरिक। सूची और सिस्टम। चयन। सी # की तरह सूची)। Thing t = new Thing(); पर Thing<Object> t = new Thing<Object>(); पर एक साधारण प्रकार पैरामीटर जोड़ने के साथ आप केवल जावा जावा कंपाइलर की ज़रूरतों को सुनिश्चित कर सकते हैं कि आप जागरूक जावा जेनेरिक का उपयोग कर रहे हैं। मैं जावा को अपनी पिछड़ी पिछड़ी संगतता के लिए कभी दोष नहीं दे सकता।

मुझे पता है कि मैं थोड़ा देर हो चुकी हूं: डी

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