2014-04-28 12 views
7

उदाहरण के बाद foo विधि हमें चेतावनी देती है, जबकि bar नहीं?जावा जेनेरिक विरासत चेतावनी

public class X { 

    static class Y {} 
    static class Z extends Y {} 

    Y y = new Y(); 

    <T extends Y> T foo() { 
     return (T) y; // warning - Unchecked cast from X.Y to T 
    } 

    Z bar() { 
     return (Z) y; // compiles fine 
    } 

} 
+5

टाइप एरर के बारे में आप कितना जानते हैं? Http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html# टाइप टाइप –

+1

मुझे लगता है कि यह स्पष्ट है कि 'foo()' को चेतावनी देना चाहिए। आप 'y' के अज्ञात सुपरक्लास' टी' पर ऑब्जेक्ट 'y' कास्टिंग कर रहे हैं। मुझे भी बहुत दिलचस्पी है कि क्यों बार() 'नहीं है। मुझे लगता है कि संकलक यह देखने में सक्षम है कि 'Z' से' Z' कास्टिंग समस्याएं उत्पन्न नहीं कर रहा है, क्योंकि 'Z' की परिभाषा उपलब्ध है। – SebastianH

+2

@ सेबेस्टियनएच: मुझे नहीं लगता कि यह एक समस्या है। – gudge

उत्तर

1

टाइप टी को कंपाइल समय पर वाई में मिटा दिया गया है, यह जेनेरिक जावा में कैसे काम करता है। इस प्रकार जब कास्ट रन टाइम पर किया जाता है तो टी का प्रकार उपलब्ध नहीं होता है, यह बाइट कोड में केवल Y है।

bar() ठीक प्रकार संकलित करता है क्योंकि सभी प्रकार की जानकारी उपलब्ध है (कास्ट विफल हो जाएगी)। लेकिन foo() इस प्रकार की जानकारी की कमी है और असफल नहीं हो सकता है, संभावित रूप से (या निश्चित रूप से, इस मामले में) विधि के प्रकार हस्ताक्षर को गलत और प्रोग्राम में बग का स्रोत बनना।

सुरक्षित रूप से ऐसा करने के लिए आपको कक्षा को स्वयं को विधि में पारित करने की आवश्यकता है।

<T extends Y> T foo(Class<T> cls) { 
    return cls.cast(y); //No type warning. Will throw an error when cast fails. 
} 
+0

हूप्स, विस्तारित बिट के बारे में भूल गए। संपादित, धन्यवाद। – ggovan

0

क्योंकि T अपने एक प्रकार टैग और Z अपने वर्ग का नाम। return (Z) y; इसकी सही प्रकार का कास्टिंग, लेकिन return (T) y; - रनटाइम में अज्ञात प्रकार कास्टिंग। जेवीएम रनटाइम में टाइप टैग के बारे में कुछ भी नहीं जानता (this ट्यूटोरियल अनुभाग देखें)। बिल्कुल संक्षेप में, return (T) y;लगभग समतुल्य return (Object) y;, यह X.Y से Object से अनचेक कास्ट है। return (Z) y; स्पष्टीकरण के लिए downcasting in Java को भी देखें।

+2

"*' रिटर्न (टी) वाई; 'लगभग समकक्ष 'वापसी (ऑब्जेक्ट) वाई;' * "वास्तव में' 'के बाद से यह' वापसी (वाई) वाई; 'के लिए बाइटकोड में बराबर है। – Pshemo

+2

@Pshemo निश्चित रूप से, सुधार के लिए धन्यवाद। – injecto

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