'इंस्टाफ़ॉफ़' ऑपरेटर इंटरफेस और कक्षाओं के लिए अलग तरह से व्यवहार करता है


88

मैं instanceofजावा में ऑपरेटर के निम्न व्यवहार के बारे में जानना चाहूंगा ।

interface C {}

class B {}

public class A {
    public static void main(String args[]) {
        B obj = new B();
        System.out.println(obj instanceof A);      //Gives compiler error
        System.out.println(obj instanceof C);      //Gives false as output
    }
}

ऐसा क्यों है? कोई संबंध नहीं है interface Cऔर class B, लेकिन यह गलत है, जबकि इसके मामले में obj instanceof Aसंकलक त्रुटि देता है?


12
नोट: यदि आप इसे बदलते हैं Object obj = new B(), तो यह संकलित करता है।
user253751

1
संकलक त्रुटि आपको क्या बताती है?
karfau

यदि class Bहै finalतो obj instanceof Cया तो संकलित नहीं करेगा, क्योंकि यदि Bकोई उपप्रकार नहीं हो सकता है, तो यह असंबंधित होने की गारंटी है C
jaco0646

जवाबों:


127

क्योंकि जावा में कोई भी बहुस्तरीय वंशानुक्रम नहीं है, यह संकलन के दौरान पूरी तरह से ज्ञात है कि objऑब्जेक्ट का प्रकार Bउप- प्रकार नहीं हो सकता है A। दूसरी ओर यह संभवतः इंटरफ़ेस का उपप्रकार हो सकता है C, उदाहरण के लिए इस मामले में:

interface C {}

class B {}

class D extends B implements C {}

public class A {
    public static void main(String args[]) {
        B obj = new D();
        System.out.println(obj instanceof C);      //compiles and gives true as output  
    }
}

इसलिए केवल obj instanceof Cअभिव्यक्ति संकलक को देखकर अग्रिम में यह नहीं बताया जा सकता है कि यह सही होगा या गलत, लेकिन obj instanceof Aयह देखकर कि यह हमेशा गलत है, इस प्रकार अर्थहीन है और आपको एक त्रुटि को रोकने में मदद करता है। यदि आप अभी भी अपने कार्यक्रम में यह अर्थहीन जाँच करना चाहते हैं, तो आप इसमें एक स्पष्ट कास्टिंग जोड़ सकते हैं Object:

System.out.println(((Object)obj) instanceof A);      //compiles fine

1
व्यर्थ की जाँच का अन्य स्वाद हैA.class.isAssignableFrom(obj.getClass())
डेविड एहरमन

मैं आपके स्पष्टीकरण से थोड़ा उलझन में हूं कि आपने कहा था कि Java has no multiple class inheritanceमैं सहमत हूं लेकिन इस मामले में इसे कैसे लागू किया जाता है क्योंकि न तो बी या ए ने किसी भी तरह का विस्तार किया है इसलिए यहाँ कई विरासत हैं। यदि आप समझा सकते हैं तो यह उपयोगी होगा?
कोडगैसर

@codegasmer उत्तर: यदि जावा ने एक वर्ग को कई अन्य वर्गों से विरासत में लेने की अनुमति दी है, तो कोई भी "क्लास डी, ए, बी" या कुछ ऐसा कर सकता है, और फिर "बी ओज = नया डी ()", और "ओबज" बना सकता है। Instof A "मूल प्रश्न संकलन में (जबकि यह वर्तमान में नहीं है) - वास्तव में इसका संकलन बेहतर था, क्योंकि इससे सत्य के मूल्यांकन की उम्मीद की जाएगी। लेकिन अगर इसे बस बी और ए दोनों के लिए कुछ भी करने की अनुमति नहीं है, तो अभिव्यक्ति "ओब्ज इन्स्टोफ ए" जहां ओबी को टाइप बी के रूप में परिभाषित किया गया है, को यथोचित रूप से निरर्थक माना जा सकता है।
mjwach

"यदि आप अभी भी यह अर्थहीन जाँच करना चाहते हैं" - तो इसे निरर्थक होने की आवश्यकता नहीं है, जैसे कि यदि यह कक्षाएं अन्य पुस्तकालय / ढांचे से हैं, तो संभावना है कि आप रनटाइम पर विभिन्न संस्करण का उपयोग करेंगे B extends A। मेरे जीवन में मुझे वास्तव में इस तरह की अजीब जांच और कास्ट करने की आवश्यकता थी जैसे (A)(Object)bकि रनटाइम में वास्तव में यह संभव था।
गोटोफाइनल

1

finalनीचे वर्ग घोषणा में संशोधक का उपयोग करके , यह गारंटी है कि कोई उपवर्ग नहीं हो सकता है Test, जो इंटरफ़ेस को लागू कर सकता है Foobar। इस मामले में, यह है कि स्पष्ट है Testऔर Foobarएक दूसरे के साथ संगत नहीं हैं:

public final class Test {

    public static void main(String[] args) {
        Test test = new Test();
        System.out.println(test instanceof Foobar); // Compiler error: incompatible types
    }
}

interface Foobar {
}

अन्यथा, यदि Testघोषित नहीं किया जाता है , तो finalयह संभव हो सकता है कि Testइंटरफ़ेस को लागू करता है। और यही कारण है कि संकलक test instanceof Foobarइस मामले में बयान की अनुमति देगा ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.