2016-09-14 15 views
5

पर ऑब्जेक्ट कास्टिंग टाइप करें हमें हाल ही में हमारे कोड में एक बग का सामना करना पड़ा जो मूल रूप से ओओपी अवधारणाओं से संबंधित था।किसी भी संग्रह प्रकार

class ABC 
{ 
    String a; 
    ABC(){ 
     a = "abc"; 
    } 
} 

public class Main { 


    static Object listABC() { 
     List<ABC> listOfABC = new ArrayList<>(); 
     listOfABC.add(new ABC()); 
     return listOfABC; 
    } 

    public static void main(String[] args) throws java.lang.Exception { 

     List<Long> listLong = (List) Main.listABC(); 
     System.out.println(listLong.get(0)); 
    } 
} 

आउटपुट: एबीसी @ 642c39d2

इस एक रन समय अपवाद बढ़ा नहीं करना चाहिए? क्या कोई मुझे सही दिशा में इंगित कर सकता है कि यह कोड अपवाद क्यों नहीं उठाता है?

+0

आपकी मौजूदा सूची का प्रकार है और आप इसे लंबे समय तक – Nimesh

+0

पर कास्टिंग कर रहे हैं हां, यह कोई रन टाइम अपवाद – rmagon

+2

@rmagon नहीं बढ़ाता है क्योंकि जेनिक्स संकलन के बाद चला गया है। आपको 'रनटाइम' अपवाद नहीं मिलेगा क्योंकि संकलक सही प्रकार की परवाह करता है। यदि जेनिक्स द्वारा परिभाषित एक अलग वर्ग के लिए 'रनटाइम' कुछ है, तो वहां कोई एक्सपिसन नहीं होगा क्योंकि 'सूची' का सामान्य प्रकार अब मौजूद नहीं है – SomeJavaGuy

उत्तर

7

जेनेरिक प्रकार मिट जाते हैं, और उनके बारे में अपने उदाहरण की जानकारी में नहीं रह गया है क्रम में मौजूद है। वे केवल एक संकलन समय सहायता हैं। कास्टिंग सूची < टी> सूची में संकलन समय पर प्रकार के बारे में जानकारी को भी छोड़ देता है, हालांकि यह अभी भी एक वैध कलाकार है।

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

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

+3

वास्तविक कहानी अधिक जटिल है, यह कहना बेहतर है कि _ इस विशेष example_ में, सामान्य प्रकार चले गए हैं। उदाहरण के लिए, किसी फ़ील्ड या विधि पैरामीटर पर पैरामीटर टाइप करें प्रतिबिंब के लिए उपलब्ध हैं; यदि आप गैर-जेनेरिक वर्ग के साथ एक सामान्य इंटरफ़ेस लागू करते हैं, तो आपके द्वारा उपयोग किए जाने वाले प्रकार के अक्षर भी उपलब्ध हैं। जावा में, मिटा एक गड़बड़ है। –

+0

@ मार्को हाँ। खैर, यह कीड़े का एक बड़ा हिस्सा है। लेकिन मैं इसे शब्द देने का कोई बेहतर तरीका नहीं जानता। मैं "इस उदाहरण में" जोड़ दूंगा। लेकिन आगे की शिकायतों को मेरे सचिव, लॉल जाना होगा। –

+0

@ मार्कोटोपोलनिक क्या आप कुछ और प्रकाश डाल सकते हैं? शायद मुझे कुछ अच्छे संसाधनों के लिए इंगित करें? – rmagon

3

उत्तर बहुत आसान है। जेनेरिक संकलन समय संगतता सुनिश्चित करने के लिए समय घटकों को संकलित कर रहे हैं। संकलन के बाद जेनेरिक चले गए हैं और इसलिए अब रनटाइम में मौजूद नहीं हैं।

Object listABC के रूप में, वापसी एक List, (List) Test.listABC(); नहीं करता है एक अपवाद फेंक करता है क्योंकि यह वैध के रूप में यह वास्तव में एक List देता है।

आप इसे List<Long> listLong पर असाइन कर सकते हैं क्योंकि रनटाइम listLong पर इसके बारे में Long सामान्य नहीं है।

परिणामस्वरूप यह गलत है, वैध निष्पादन योग्य कोड।

भी एकमात्र कारण यह काम करता है क्योंकि आपके एक गलत प्रकार से कॉल करने के रूप में आप निम्न उदाहरण में देख सकते हैं की कोशिश कर रहा अन्यथा you'd एक Exception मिलता है, है कि वहाँ एक PrintStream#println(Object) तरीका है।

static Object listABC() { 
    List<Test> listOfABC = new ArrayList<>(); 
    listOfABC.add(new Test()); 
    return listOfABC; 
} 

public static void main(String[] args) throws java.lang.Exception { 

    List<Long> listLong = (List) Test.listABC(); 
    System.out.println(listLong.get(0)); 
    test(listLong.get(0)); 
} 

private static void test(Long longvalue) { 
    System.out.println("TEST"); 
} 

ओ/पी

[email protected] 
Exception in thread "main" java.lang.ClassCastException: ABC cannot be cast to java.lang.Long 
at ABC.main(ABC.java:19) 
संबंधित मुद्दे