क्या इंस्टाल कॉल करने से पहले अशक्त जांच की आवश्यकता है?


1354

null instanceof SomeClassलौटेंगे falseया फेंक देंगे NullPointerException?


यह 'महत्वपूर्ण' या कम से कम बहुत उपयोगी है 'किसी भी तुलना या बराबरी या इसी तरह की विधि के लिए' सर्वोत्तम-अभ्यास 'शुरू (या बहुत जल्दी) लाइन के रूप में जो केवल उसी प्रकार की गैर-अशक्त वस्तुओं पर सफल होने के लिए डिज़ाइन की गई है, और आपको एक ही लाइन में 'मूर्खतापूर्ण मामलों' के खिलाफ गार्ड। कम कोड = कम कीड़े।

13
में तौलना "क्या यह उपयोगी है?" बहस - मैंने अपना स्वयं का जावा कोड कभी नहीं लिखा है (इसलिए आसानी से पता नहीं है कि चश्मा कहाँ हैं, और परीक्षण संकलित करना बहुत गैर-तुच्छ होगा), लेकिन मैं वर्तमान में मैन्युअल रूप से जावा को जावास्क्रिप्ट में परिवर्तित कर रहा हूं। मेरा कोड एक अशक्त संदर्भ पर विफल हो रहा था, और इसे गुगली करने से मुझे स्वीकृत उत्तर देखने को मिला, जिसने पुष्टि की कि यह अपेक्षित व्यवहार था और मुझे एक अंतर्निहित शून्य जांच याद आ रही थी। बहुत उपयोगी है, मेरे मामले में।
स्कॉट Mermelstein

जवाबों:


1838

नहीं, उदाहरण के उपयोग से पहले एक अशक्त जांच की आवश्यकता नहीं है।

अभिव्यक्ति x instanceof SomeClassहै falseअगर xहै null

जावा भाषा विशिष्टता से, खंड 15.20.2, "टाइप तुलना ऑपरेटर उदाहरण" :

"रन के समय में, instanceofऑपरेटर का परिणाम होता है trueअगर RelationalExpression काnull मान नहीं है और संदर्भ को बिना किसी संदर्भ के बिना संदर्भ संदर्भ में डाला जा सकता है ClassCastException। अन्यथा परिणाम है false।"

इसलिए यदि ऑपरेंड शून्य है, तो परिणाम गलत है।


377
यह उत्तर की तुलना में अधिक सही है try itक्योंकि वर्तमान व्यवहार गारंटीकृत व्यवहार के समान नहीं है
ल्यूक

3
यह सवाल जोशुआ बलोच के अध्याय के दौरान वस्तु समानता पर Effective Java- amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683
केविन मेरेडिथ

17
विशेष रूप से, आइटम 8 में, वह नोट करता है कि समान () विधियों में, एक इंस्टोफ़ ऑपरेटर दो उद्देश्यों को पूरा करता है - यह सत्यापित करता है कि तर्क गैर-अशक्त और सही प्रकार का है। "... [एस] ओ आपको एक अलग अशक्त जांच की आवश्यकता नहीं है।"
एंडी थॉमस

2
@BenThurley - जावा का instanceofऑपरेटर लगभग 1.0 साल पहले जारी किए गए जावा 1.0 का हिस्सा था। मौजूदा कोड को तोड़ने के तरीके में अब व्यवहार बदलना संभव नहीं है, उस भारी लागत से कुछ लाभ अनुपस्थित हैं। बीस साल पहले, हो सकता है कि यदि सही तर्क दिया जा सकता है, या एक अशक्त तर्क के लिए अपवाद फेंकने के लिए सही वापसी के लिए तर्क हो सकते हैं। लेकिन उन परिभाषाओं में अलग-अलग अशक्त जांच की आवश्यकता होती है।
एंडी थॉमस

3
@BenThurley - व्यवहार की गारंटी जावा विनिर्देशों के अतीत और वर्तमान से मिलती है। मुझे लगता है कि ल्यूक की बात वर्तमान के गारंटीकृत व्यवहार को निर्धारित करने में प्रयोग की सीमाओं को संबोधित करती है।
एंडी थॉमस

267

instanceofरिटर्न के लिए पहले ऑपरेंड के रूप में एक शून्य संदर्भ का उपयोग करना false


268
(और अब Google में इस सवाल को खोजने में 10 सेकंड लगते हैं)
PL_kolek

73

वास्तव में बहुत अच्छा सवाल। मैंने सिर्फ अपने लिए कोशिश की।

public class IsInstanceOfTest {

    public static void main(final String[] args) {

        String s;

        s = "";

        System.out.println((s instanceof String));
        System.out.println(String.class.isInstance(s));

        s = null;

        System.out.println((s instanceof String));
        System.out.println(String.class.isInstance(s));
    }
}

प्रिंटों

true
true
false
false

JLS / 15.20.2। कम्पैरिजन ऑपरेटर टाइपो टाइप करें

रन टाइम पर, instanceofऑपरेटर का परिणाम यह trueहोता है कि जब RelationalExpression का मान नहीं है nullऔर संदर्भ को बिना उठाए बिना ReferenceType में डाला जा सकता है ClassCastException। अन्यथा परिणाम है false

एपीआई / कक्षा # अंतर्ज्ञान (वस्तु) है

यदि यह Classऑब्जेक्ट किसी इंटरफ़ेस का प्रतिनिधित्व करता है, तो यह विधि वापस आती है trueयदि वर्ग या निर्दिष्ट Objectतर्क का कोई सुपरक्लास इस इंटरफ़ेस को लागू करता है; यह falseअन्यथा लौटता है। यदि यह Classऑब्जेक्ट एक आदिम प्रकार का प्रतिनिधित्व करता है, तो यह विधि वापस आती है false


भ्रमित करने की तरह। s एक स्ट्रिंग है क्योंकि यह "स्ट्रिंग s" कहता है, s स्ट्रिंग नहीं है क्योंकि यह शून्य है। तो क्या नरक है?
काई वांग

1
@ केकईंग sएक वस्तु संदर्भ चर है। यह वास्तव में मौजूदा वस्तु ( "") को संदर्भित कर सकता है या यह (a) nullशाब्दिक संदर्भ को संदर्भित कर सकता है।
जिन क्वॉन

मैं अभी भी असमंजस में हूँ। s अब शून्य हो सकता है, लेकिन इसे केवल एक स्ट्रिंग उदाहरण के लिए बाद में इंगित किया जा सकता है। इसे एक इंटेगर की तरह इंगित नहीं किया जा सकता है। तो यह अभी भी एक प्रकार की स्ट्रिंग है, यहां तक ​​कि यह एक अशक्त है। बस बहुत मतलब नहीं है ...
काई वांग

@KaiWang आप चर प्रकार को वास्तविक वस्तु के प्रकार के साथ भ्रमित कर रहे हैं। चर उदाहरण नहीं हैं; वे प्रभावी रूप से सिर्फ संकेत कर रहे हैं। nullस्ट्रिंग डेटा नहीं है, इससे कोई फर्क नहीं पड़ता कि चर किस ओर इशारा कर रहा है। उदाहरण के लिए, के s instanceof Stringरूप में ही नहीं है field.getType().equals(String.class)
मैथ्यू

@KaiWang आप कल्पना करने के लिए कि कॉल में है , वास्तविक मूल्य के साथ बदल जाता है ताकि बन जाएगा और । इसके बारे में इस तरह से सोचना अधिक समझ में आ सकता है। s instanceof Strings"" instanceof Stringnull instanceof String
टिमो तुर्शमन 17

24

नहीं यह नहीं। यदि इसका पहला ऑपरेंड है, तो instanceofवापस आ जाएगा ।falsenull


16

बस एक tidbit के रूप में :

यहां तक ​​कि लौट आएगा ।(((A)null)instanceof A)false


(यदि टाइपकास्टिंग nullआश्चर्यजनक लगता है, तो कभी-कभी आपको ऐसा करना पड़ता है, उदाहरण के लिए इस तरह की स्थितियों में:

public class Test
{
  public static void test(A a)
  {
    System.out.println("a instanceof A: " + (a instanceof A));
  }

  public static void test(B b) {
    // Overloaded version. Would cause reference ambiguity (compile error)
    // if Test.test(null) was called without casting.
    // So you need to call Test.test((A)null) or Test.test((B)null).
  }
}

तो Test.test((A)null)छपेगा a instanceof A: false।)


पुनश्च: यदि आप काम पर रख रहे हैं, तो कृपया इसे नौकरी के साक्षात्कार प्रश्न के रूप में उपयोग न करें। : डी


7

नहीं । जावा शाब्दिक nullकिसी भी वर्ग का उदाहरण नहीं है। इसलिए यह किसी भी वर्ग का उदाहरण नहीं हो सकता । instanceof या तो वापस आ जाएगी falseयाtrue इसलिए <referenceVariable> instanceof <SomeClass>रिटर्न falseजब referenceVariableमान शून्य है।


5
यह स्पष्टीकरण अजीब से गोलाकार लगता है ... लेकिन मुझे पता है कि आपका क्या मतलब है :-)
क्रिश

@ क्रिस ty टिप्पणी के लिए मैं तुम्हें क्या मतलब है :)। एक उत्तर को थोड़ा संपादित किया :)।
डेवलपर Marius ėilėnas

1

instanceofऑपरेटर स्पष्ट की जरूरत नहीं है null, चेक के रूप में यह फेंक नहीं है एक NullPointerExceptionसंकार्य है यदि null

रन के समय में, instanceofऑपरेटर का परिणाम सही है यदि संबंधपरक अभिव्यक्ति का मूल्य नहीं है nullऔर संदर्भ को क्लास के अपवाद को उठाए बिना संदर्भ प्रकार में डाला जा सकता है।

यदि ऑपरेंड है null, तो instanceofऑपरेटर लौटता है falseऔर इसलिए, स्पष्ट रूप से अशक्त चेक की आवश्यकता नहीं होती है।

नीचे दिए गए उदाहरण पर विचार करें,

public static void main(String[] args) {
         if(lista != null && lista instanceof ArrayList) {                     //Violation
                System.out.println("In if block");
         }
         else {
                System.out.println("In else block");
         }
}

इसका सही उपयोग instanceofनीचे दिखाया गया है,

public static void main(String[] args) {
      
         if(lista instanceof ArrayList){                     //Correct way
                  System.out.println("In if block");
         }
            else {
                 System.out.println("In else block");
         }  
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.