java - जावा आपको एक संग्रह में क्यों जाने देता है?




collections interface (2)

कंपाइलर कोड को एक प्रकार के इंटरफ़ेस में डालने से नहीं रोकता है, जब तक कि यह सुनिश्चित न हो जाए कि संबंध असंभव है।

यदि लक्ष्य प्रकार एक इंटरफ़ेस है, तो यह समझ में आता है क्योंकि Foo विस्तार करने वाला एक वर्ग Map<String, String> को लागू कर सकता है। हालांकि, ध्यान दें कि यह केवल Foo रूप में काम करता है final नहीं है । यदि आपने अपनी कक्षा को final class Foo साथ घोषित किया, तो वह कास्ट काम नहीं करेगा।

यदि लक्ष्य प्रकार एक वर्ग है, तो इस मामले में यह बस विफल हो जाएगा (प्रयास करें (HashMap<String, String>) this ), क्योंकि कंपाइलर निश्चित रूप से जानता है कि Foo और HashMap बीच संबंध असंभव है।

संदर्भ के लिए, ये नियम JLS-5.5.1 (T = लक्ष्य प्रकार - Map<String, String> , S = स्रोत प्रकार - Foo ) में वर्णित हैं

यदि T [लक्ष्य प्रकार] एक इंटरफ़ेस प्रकार है:

  • यदि S एक अंतिम वर्ग (.18.1.1) नहीं है, तो, यदि T का एक सुपरपाइप X मौजूद है, और S का एक सुपरपाइप Y, जैसे कि X और Y, दोनों अलग-अलग प्रकार के मानकीकृत प्रकार हैं, और यह कि X का विलोपन। और Y समान हैं, एक संकलन-समय त्रुटि उत्पन्न होती है।
    अन्यथा, कलाकार हमेशा संकलन समय पर कानूनी होता है (क्योंकि यदि S T को लागू नहीं करता है, तो S का उपवर्ग)।

  • यदि एस एक अंतिम वर्ग (.18.1.1) है, तो एस को टी को लागू करना होगा, या एक संकलन-समय त्रुटि उत्पन्न हो सकती है।

उद्धृत पाठ में बोल्ड-इटैलिक टिप्पणी पर ध्यान दें।

इस सवाल का पहले से ही यहाँ एक जवाब है:

मेरे पास एक सरल foo वर्ग है, और मैं किसी भी संकलक त्रुटि के बिना संग्रह इंटरफ़ेस (या तो Map या List ) में डालने में सक्षम हूं। ध्यान दें कि Foo वर्ग किसी भी इंटरफ़ेस को लागू नहीं करता है या किसी अन्य वर्ग का विस्तार नहीं करता है।

public class Foo {

    public List<String> getCollectionCast() {
        return (List<String>) this;    // No compiler error
    }

    public Map<String, String> getCollection2Cast() {
        return (Map<String, String>) this;    // No compiler error
    }

    public Other getCast() {
        return (Other)this;     // Incompatible types. Cannot cast Foo to Other
    }

    public  static class Other {
        // Just for casting demo
    }

}

जब मैं Foo वर्ग को एक संग्रह में लाने की कोशिश करता हूं तो जावा कंपाइलर असंगत प्रकार की त्रुटि क्यों नहीं लौटाता है?

Foo Collection लागू नहीं करता है। मैं एक असंगत प्रकार की त्रुटि की उम्मीद करूंगा, क्योंकि वर्तमान Foo वर्ग हस्ताक्षर को देखते हुए, यह एक Collection नहीं हो सकता है।


यह इसलिए नहीं है क्योंकि वे संग्रह कक्षाएं हैं, यह इसलिए है क्योंकि वे इंटरफेस हैं Foo उन्हें लागू नहीं करता है, लेकिन यह उपवर्ग कर सकता है। इसलिए यह संकलन-समय की त्रुटि नहीं है, क्योंकि उप विधियों के लिए वे विधियाँ मान्य हो सकती हैं। रनटाइम के दौरान , अगर this उन इंटरफेस को लागू करने वाले वर्ग का नहीं है, तो स्वाभाविक रूप से यह रनटाइम त्रुटि है।

यदि आप List<String> को ArrayList<String> , तो आपको इसके लिए एक कंपाइलर-टाइम त्रुटि मिलेगी, वह भी, क्योंकि एक Foo उपवर्ग List को लागू कर सकता है, लेकिन ArrayList ( Foo नहीं करता है) का विस्तार नहीं कर सकता है। इसी तरह, यदि आप Foo final , तो कंपाइलर आपको आपके इंटरफ़ेस कास्ट के लिए एक त्रुटि देगा क्योंकि यह जानता है कि वे कभी भी सच नहीं हो सकते हैं (क्योंकि Foo में उपवर्ग नहीं हो सकते हैं, और उन इंटरफेस को लागू नहीं करते हैं)।






casting