यह एक नहीं बल्कि आम गलती है:
ForEachLoop f = new ForEachLoop();
होना चाहिए
ForEachLoop<Something> f = new ForEachLoop<Something>();
आप (कच्चे प्रकार का उपयोग करते है जो आप नहीं करना चाहिए) संकलक उस उदाहरण के लिए सभी सामान्य जानकारी मिटा देगा, भले ही यह टाइप पैरामीटर टी नहीं है, इसे संगत बनाने के लिए पूर्व 1.5 कोड।
यदि आप जावा 1.4 या उससे कम के लिए लिख रहे हैं तो केवल कच्चे प्रकार का उपयोग करें, इस मामले में आपको कोई जेनरिक्स नहीं होना चाहिए। बाइटकोड स्तर पर विधि टाइप एरर के बाद संग्रह (कच्ची) लौटाती है। आम तौर पर, यदि उदाहरण में सामान्य प्रकार सेट होता है, तो जब आप संग्रह पर get
करने का प्रयास करते हैं, तो संकलक जेनेरिक जानकारी का उपयोग यह तय करने के लिए करेगा कि उसे स्ट्रिंग वापस करनी चाहिए, और फिर बाइटकोड स्तर पर यह स्वचालित रूप से प्राप्त ऑब्जेक्ट को प्राप्त करता है संग्रह से स्ट्रिंग तक (क्योंकि यह स्ट्रिंग होने की गारंटी है)। लेकिन यदि आप कच्चे प्रकार का उपयोग करते हैं तो संकलक सभी सामान्य जानकारी को अनदेखा कर देगा और अब आपके लिए ऑब्जेक्ट को स्वचालित रूप से नहीं डालेगा।
संपादित: कच्चे प्रकार पर अनुभाग में इन बातों को कर रहे हैं:
उपरोक्त नियमों का एक अन्य निहितार्थ यह है कि एक कच्चे प्रकार की एक सामान्य भीतरी वर्ग में ही केवल एक के रूप में इस्तेमाल किया जा सकता है कच्चे प्रकार:
class Outer<T>{
class Inner<S> {
S s;
}
}
यह आंशिक रूप से कच्चे प्रकार के रूप में इनर तक पहुँचने के लिए संभव नहीं है (एक "दुर्लभ" प्रकार)
Outer.Inner<Double> x = null; // illegal
Double d = x.s;
क्योंकि बाहरी ही कच्चे है, इसलिए इनर सहित सब अपने भीतर की कक्षाएं, कर रहे हैं, और इसलिए यह संभव यह करने के लिए किसी भी प्रकार के पैरामीटर पास नहीं है।
कच्चे प्रकार के उपयोग की अनुमति विरासत कोड की संगतता के लिए रियायत के रूप में की जाती है। में कच्चे प्रकारों का उपयोग की शुरूआत के बाद लिखा गया जावा प्रोग्रामिंग भाषा में सामान्यता दृढ़ता से निराश होती है। यह संभव है कि के भविष्य के संस्करण जावा प्रोग्रामिंग भाषा कच्चे प्रकार के उपयोग को अस्वीकार कर देगी।
यह एक संकलन समय त्रुटि एक कच्चे प्रकार के रूप में एक पैरामिट्रीकृत प्रकार का एक प्रकार सदस्य का उपयोग करने के प्रयास करने के लिए है।
इसका मतलब है कि पर "दुर्लभ" प्रकार प्रतिबंध मामले में जहां योग्यता प्रकार पैरामिट्रीकृत है तक फैली हुई है, लेकिन हम एक कच्चे प्रकार के रूप में आंतरिक वर्ग उपयोग करने का प्रयास:
Outer<Integer>.Inner x = null; // illegal
यह मामले के विपरीत हम ऊपर चर्चा की है। इस आधा बेक्ड प्रकार के लिए कोई व्यावहारिक औचित्य नहीं है। विरासत कोड में, पैरामीटर का कोई भी प्रकार उपयोग नहीं किया जाता है। गैर-विरासत कोड में, हमें सामान्य प्रकार सही ढंग से उपयोग करना चाहिए और सभी आवश्यक वास्तविक प्रकार पैरामीटर को पारित करना चाहिए।
ध्यान दें कि इनर क्लास में इसका स्वयं का प्रकार पैरामीटर बाहरी वर्ग में से एक से स्वतंत्र है, और यह अभी भी मिटा दिया जाता है। असल में वे नहीं चाहते हैं कि हम एक ही उदाहरण पर कच्चे और जेनेरिक प्रकारों को मिलाएं, क्योंकि यह किसी भी संस्करण में समझ में नहीं आता है (प्री 1.5 में, जेनेरिक हिस्सा एक त्रुटि होगी, 1.5+ में कच्चे प्रकार को हतोत्साहित किया जाता है, और यहां तक कि भविष्य के संस्करणों से हटाया जा सकता है)
तो फिर वहाँ भी इस है:
एक निर्माता के प्रकार (§8.8), उदाहरण विधि (§8.8, §9.4), या गैर स्थिर क्षेत्र (§8.3) कच्चे प्रकार सी जो कि सुपरक्लास या superinterfaces से विरासत में नहीं मिला है जेनेरिक घोषणा में इसके प्रकार का क्षरण है सी के लिए इसी एक कच्चे प्रकार सी के एक स्थिर सदस्य की प्रकार सामान्य घोषणा में अपनी तरह करने के लिए इसी सी
रूप में ही है यह वास्तविक प्रकार पैरामीटर प्रदान करने के एक संकलन समय त्रुटि है एक गैर-स्थैतिक कच्चे प्रकार के प्रकार का सदस्य जो अपने सुपरक्लास या superinterfaces से विरासत में नहीं है।
जो कहता है कि रचनाकार, उदाहरण विधियों और गैर स्थैतिक क्षेत्रों को कच्चे उदाहरण में कच्चे के रूप में माना जाएगा। स्थिर सदस्यों को वैसे भी जेनेरिक माना जाएगा, क्योंकि उन्हें एक उदाहरण की आवश्यकता नहीं है।
दिलचस्प लगता है और तार्किक। क्या आप कृपया जावा विनिर्देश को इंगित कर सकते हैं कि "कंपाइलर सभी सामान्य जानकारी मिटा देगा भले ही यह टाइप पैरामीटर टी नहीं है"? –
जेएलएस से कुछ स्निपेट, और मेरी (शायद सीमित) समझ में जोड़ा गया। –
मैं आपके उत्तर को अवशोषित करने की कोशिश करूंगा, लेकिन मुझे कुछ समय लगेगा। धन्यवाद –