खोज…


परिचय

कई जावा प्रोग्रामिंग भाषा मिसयूज सही ढंग से संकलित होने के बावजूद गलत परिणाम उत्पन्न करने के लिए एक कार्यक्रम का आयोजन कर सकती है। यह विषय मुख्य उद्देश्य उनके कारणों के साथ आम नुकसान की सूची बनाना है, और ऐसी समस्याओं में गिरने से बचने के लिए सही तरीके का प्रस्ताव करना है।

टिप्पणियों

यह विषय जावा भाषा के सिंटैक्स के विशिष्ट पहलुओं के बारे में है जो या तो त्रुटि प्रवण हैं या जिनका कुछ निश्चित तरीकों से उपयोग नहीं किया जाना चाहिए।

नुकसान - विधि दृश्यता की अनदेखी

यहां तक कि अनुभवी जावा डेवलपर्स को लगता है कि जावा में केवल तीन सुरक्षा संशोधक हैं। भाषा वास्तव में चार है! दृश्यता के पैकेज निजी (उर्फ डिफ़ॉल्ट) स्तर को अक्सर भुला दिया जाता है।

आपको ध्यान देना चाहिए कि आप किन तरीकों को सार्वजनिक करते हैं। एक आवेदन में सार्वजनिक तरीके अनुप्रयोग के दृश्य एपीआई हैं। यह जितना संभव हो उतना छोटा और कॉम्पैक्ट होना चाहिए, खासकर यदि आप एक पुन: प्रयोज्य पुस्तकालय लिख रहे हैं (देखें भी ठोस सिद्धांत)। इसी तरह सभी तरीकों की दृश्यता पर विचार करना महत्वपूर्ण है, और केवल जहां उचित हो संरक्षित या पैकेज का उपयोग करना है।

जब आप तरीकों कि सार्वजनिक निजी होना चाहिए घोषित, तुम वर्ग की आंतरिक कार्यान्वयन विवरण का खुलासा।

इसका एक आधार यह है कि आप केवल अपने वर्ग के सार्वजनिक तरीकों का परीक्षण करते हैं - वास्तव में आप केवल सार्वजनिक विधियों का परीक्षण कर सकते हैं। निजी तरीकों की दृश्यता बढ़ाने के लिए सिर्फ उन तरीकों के खिलाफ यूनिट परीक्षण चलाने में सक्षम होना बुरा है। सार्वजनिक तरीकों का परीक्षण करना जो अधिक प्रतिबंधात्मक दृश्यता वाले तरीकों को कहते हैं, पूरे एपीआई का परीक्षण करने के लिए पर्याप्त होना चाहिए। आपको केवल यूनिट परीक्षण की अनुमति देने के लिए और अधिक सार्वजनिक तरीकों से अपने एपीआई का विस्तार नहीं करना चाहिए।

नुकसान - एक 'स्विच' मामले में एक 'ब्रेक' गुम

ये जावा मुद्दे बहुत शर्मनाक हो सकते हैं, और कभी-कभी उत्पादन में चलने तक अनदेखे रह जाते हैं। स्विच स्टेटमेंट में निर्णायक व्यवहार अक्सर उपयोगी होता है; हालाँकि, एक "ब्रेक" कीवर्ड न मिलने पर ऐसा व्यवहार वांछित नहीं होने पर विनाशकारी परिणाम हो सकते हैं। यदि आप नीचे दिए गए कोड उदाहरण में "केस 0" में "ब्रेक" डालना भूल गए हैं, तो प्रोग्राम "जीरो" और उसके बाद "वन" लिख देगा, क्योंकि यहां से अंदर प्रवाह नियंत्रण पूरे "स्विच" स्टेटमेंट तक जाएगा यह एक "ब्रेक" तक पहुँचता है। उदाहरण के लिए:

public static void switchCasePrimer() {
        int caseIndex = 0;
        switch (caseIndex) {
            case 0:
                System.out.println("Zero");
            case 1:
                System.out.println("One");
                break;
            case 2:
                System.out.println("Two");
                break;
            default:
                System.out.println("Default");
        }
}

ज्यादातर मामलों में, क्लीनर समाधान इंटरफेस का उपयोग करना होगा और अलग-अलग कार्यान्वयन में विशिष्ट व्यवहार के साथ कोड को स्थानांतरित करना होगा ( विरासत पर रचना )

यदि एक स्विच-स्टेटमेंट अपरिहार्य है, तो ऐसा होने पर "अपेक्षित" गिरावट को दस्तावेज करने की सिफारिश की जाती है। इस तरह से आप साथी डेवलपर्स को दिखाते हैं कि आप लापता ब्रेक के बारे में जानते हैं, और यह अपेक्षित व्यवहार है।

switch(caseIndex) {
    [...]
    case 2:
        System.out.println("Two");
        // fallthrough
    default:
        System.out.println("Default");

नुकसान - अर्धविराम और लापता ब्रेसिज़ मिस्ड

यह एक गलती है जो जावा शुरुआती के लिए वास्तविक भ्रम का कारण बनती है, कम से कम पहली बार जब वे ऐसा करते हैं। इसे लिखने के बजाय:

if (feeling == HAPPY)
    System.out.println("Smile");
else
    System.out.println("Frown");

वे गलती से यह लिखते हैं:

if (feeling == HAPPY);
    System.out.println("Smile");
else
    System.out.println("Frown");

जब जावा कंपाइलर उन्हें बताता है कि else गलत स्थान पर है, else वह हैरान हो जाता है। जावा कम्पाइलर ऊपर की व्याख्या के साथ इस प्रकार है:

if (feeling == HAPPY)
    /*empty statement*/ ;
System.out.println("Smile");   // This is unconditional
else                           // This is misplaced.  A statement cannot
                               // start with 'else'
System.out.println("Frown");

अन्य मामलों में, संकलन त्रुटियां नहीं होंगी, लेकिन कोड वह नहीं करेगा जो प्रोग्रामर का इरादा है। उदाहरण के लिए:

for (int i = 0; i < 5; i++);
    System.out.println("Hello");

केवल एक बार "हैलो" प्रिंट करता है। एक बार फिर, स्परियस अर्धविराम का मतलब है कि लूप के for शरीर एक खाली बयान है। इसका मतलब है कि println कॉल जो अनुसरण करता है वह बिना शर्त है।

एक और भिन्नता:

for (int i = 0; i < 5; i++);
    System.out.println("The number is " + i);

यह i लिए एक "प्रतीक नहीं ढूंढ सकता" त्रुटि देगा। सुस्पष्ट अर्धविराम की उपस्थिति का मतलब है कि println कॉल i इसके दायरे से बाहर का उपयोग करने का प्रयास कर रहा i

उन उदाहरणों में, एक सीधे-आगे का समाधान है: बस संयमी अर्धविराम को हटा दें। हालाँकि, इन उदाहरणों से कुछ गहरे सबक लिए जा सकते हैं:

  1. जावा में अर्धविराम "वाक्यात्मक शोर" नहीं है। अर्धविराम की उपस्थिति या अनुपस्थिति आपके कार्यक्रम के अर्थ को बदल सकती है। हर पंक्ति के अंत में उन्हें न जोड़ें।

  2. अपने कोड के इंडेंटेशन पर भरोसा न करें। जावा भाषा में, लाइन की शुरुआत में अतिरिक्त व्हाट्सएप को कंपाइलर द्वारा अनदेखा किया जाता है।

  3. एक स्वचालित indenter का उपयोग करें। सभी आईडीई और कई सरल पाठ संपादक समझते हैं कि जावा कोड को सही ढंग से कैसे इंडेंट किया जाए।

  4. यह सबसे महत्वपूर्ण सबक है। नवीनतम जावा शैली दिशानिर्देशों का पालन करें, और "तब" और "और" बयानों और लूप के बॉडी स्टेटमेंट के चारों ओर ब्रेसिज़ लगाएं। खुली ब्रेस ( { ) नई लाइन पर नहीं होनी चाहिए।

यदि प्रोग्रामर ने शैली नियमों का पालन किया है, तो गलत उदाहरण वाले अर्धविराम के साथ if उदाहरण इस प्रकार होगा:

if (feeling == HAPPY); {
    System.out.println("Smile");
} else {
    System.out.println("Frown");
}

यह एक अनुभवी आंख को अजीब लगता है। यदि आप उस कोड को ऑटो-इंडेंट करते हैं, तो यह संभवतः इस तरह दिखाई देगा:

if (feeling == HAPPY); {
                           System.out.println("Smile");
                       } else {
                           System.out.println("Frown");
                       }

जो एक शुरुआत भी गलत के रूप में बाहर खड़ा होना चाहिए।

नुकसान - ब्रेसिज़ को छोड़ना: "झूलना अगर" और "लटकना" जैसी समस्याएं

ओरेकल जावा स्टाइल गाइड के नवीनतम संस्करण में कहा गया है कि "तत्कालीन" और "अन्य" बयान if एक बयान में हमेशा "ब्रेसिज़" या "घुंघराले कोष्ठक" में संलग्न होना चाहिए। इसी तरह के नियम विभिन्न लूप स्टेटमेंट्स के निकायों पर लागू होते हैं।

if (a) {           // <- open brace
    doSomething();
    doSomeMore();
}                  // <- close brace

यह वास्तव में जावा भाषा सिंटैक्स द्वारा आवश्यक नहीं है। वास्तव में, यदि "तत्कालीन" भाग if एक बयान का एक बयान है, तो ब्रेसिज़ को छोड़ना कानूनी है

if (a)
    doSomething();

या और भी

if (a) doSomething();

हालांकि जावा शैली के नियमों की अनदेखी करने और ब्रेसिज़ को छोड़ने में खतरे हैं। विशेष रूप से, आप काफी जोखिम बढ़ाते हैं कि दोषपूर्ण इंडेंटेशन के साथ कोड गलत हो जाएगा।

"झूलना अगर" समस्या:

ऊपर से उदाहरण कोड पर विचार करें, ब्रेसिज़ के बिना फिर से लिखा गया।

if (a)
   doSomething();
   doSomeMore();

यह कोड यह कहता प्रतीत होता है कि doSomething और doSomeMore दोनों कॉल तब होती हैं यदि केवल और यदि a true । वास्तव में, कोड गलत तरीके से इंडेंट किया गया है। जावा भाषा की विशिष्टता है कि doSomeMore() कॉल एक अलग स्टेटमेंट है if स्टेटमेंट के बाद। सही इंडेंटेशन निम्नानुसार है:

if (a)
   doSomething();
doSomeMore();

"लटकती हुई" समस्या

एक दूसरी समस्या तब दिखाई देती है जब हम मिश्रण में else मिलाते हैं। लापता ब्रेसिज़ के साथ निम्नलिखित उदाहरण पर विचार करें।

if (a)
   if (b)
      doX();
   else if (c)
      doY(); 
else
   doZ();

ऊपर दिए गए कोड से लगता है कि doZ को doZ जाएगा जब a false । वास्तव में, इंडेंटेशन एक बार फिर गलत है। कोड के लिए सही इंडेंटेशन है:

if (a)
   if (b)
      doX();
   else if (c)
      doY(); 
   else
      doZ();

यदि कोड जावा शैली के नियमों के अनुसार लिखा गया था, तो यह वास्तव में इस तरह दिखेगा:

if (a) {
   if (b) {
      doX();
   } else if (c) {
      doY(); 
   } else {
      doZ();
   }
}

यह बताने के लिए कि बेहतर क्यों है, मान लीजिए कि आपने गलती से कोड को गलत तरीके से प्रस्तुत किया था। आप कुछ इस तरह से समाप्त कर सकते हैं:

if (a) {                         if (a) {
   if (b) {                          if (b) {
      doX();                            doX();
   } else if (c) {                   } else if (c) {
      doY();                            doY();
} else {                         } else {
   doZ();                            doZ();
}                                    }
}                                }

लेकिन दोनों मामलों में, एक गलत जावा प्रोग्रामर की नज़र में गलत इंडेंट कोड "गलत दिखता है"।

नुकसान - ओवरराइडिंग के बजाय ओवरलोडिंग

निम्नलिखित उदाहरण पर विचार करें:

public final class Person {
    private final String firstName;
    private final String lastName;
   
    public Person(String firstName, String lastName) {
        this.firstName = (firstName == null) ? "" : firstName;
        this.lastName = (lastName == null) ? "" : lastName;
    }

    public boolean equals(String other) {
        if (!(other instanceof Person)) {
            return false;
        }
        Person p = (Person) other;
        return firstName.equals(p.firstName) &&
                lastName.equals(p.lastName);
    }

    public int hashcode() {
        return firstName.hashCode() + 31 * lastName.hashCode();
    }
}

यह कोड अपेक्षा के अनुरूप व्यवहार करने वाला नहीं है। समस्या यह है कि Person लिए equals और hashcode तरीके Object द्वारा परिभाषित मानक तरीकों को ओवरराइड नहीं करते हैं।

  • equals पद्धति में गलत हस्ताक्षर हैं। इसे equals(Object) नहीं equals(String) equals(Object) घोषित किया जाना चाहिए।
  • hashcode विधि में गलत नाम है। यह hashCode() होना चाहिए hashCode() राजधानी सी पर ध्यान दें)।

इन गलतियों का मतलब है कि हमने आकस्मिक अधिभार घोषित किया है, और इनका उपयोग नहीं किया जाएगा यदि Person का उपयोग पॉलीमॉर्फिक संदर्भ में किया जाता है।

हालांकि, इससे निपटने के लिए एक सरल तरीका है (जावा 5 से आगे)। जब भी आप अपनी विधि को ओवरराइड करने का इरादा रखते हैं तो @Override एनोटेशन का उपयोग करें:

जावा एसई 5
public final class Person {
    ...

    @Override
    public boolean equals(String other) {
        ....
    }

    @Override
    public hashcode() {
        ....
    }
}

जब हम मेथड @Override को मेथड डिक्लेरेशन में जोड़ते हैं, तो कंपाइलर चेक करेगा कि मेथड एक सुपरक्लास या इंटरफेस में घोषित मेथड को ओवरराइड (या कार्यान्वित) करता है। तो ऊपर के उदाहरण में, संकलक हमें दो संकलन त्रुटियां देगा, जो हमें गलती के लिए सचेत करने के लिए पर्याप्त होना चाहिए।

गड्ढा - अष्टक शाब्दिक

निम्नलिखित कोड स्निपेट पर विचार करें:

// Print the sum of the numbers 1 to 10
int count = 0;
for (int i = 1; i < 010; i++) {    // Mistake here ....
    count = count + i;
}
System.out.println("The sum of 1 to 10 is " + count);

एक जावा शुरुआतकर्ता को यह जानकर आश्चर्य हो सकता है कि उपरोक्त कार्यक्रम गलत उत्तर को प्रिंट करता है। यह वास्तव में 1 से 8 की संख्या का योग बनाता है।

कारण यह है कि एक पूर्णांक शाब्दिक, जो अंक शून्य ('0') से शुरू होता है, जावा कंपाइलर द्वारा एक ऑक्टिकल शाब्दिक के रूप में व्याख्या किया जाता है, न कि एक दशमलव शाब्दिक के रूप में जैसा कि आप उम्मीद कर सकते हैं। इस प्रकार, 010 अष्टक संख्या 10 है, जो दशमलव में 8 है।

नुकसान - मानक वर्गों के समान नामों के साथ कक्षाओं की घोषणा

कभी-कभी, जो प्रोग्रामर जावा में नए हैं, वे एक वर्ग को एक नाम के साथ परिभाषित करने की गलती करते हैं जो व्यापक रूप से उपयोग किए जाने वाले वर्ग के समान है। उदाहरण के लिए:

package com.example;

/**
 * My string utilities
 */
public class String {
    ....
}

तब उन्हें आश्चर्य होता है कि उन्हें अप्रत्याशित त्रुटियां क्यों मिलीं। उदाहरण के लिए:

package com.example;

public class Test {
    public static void main(String[] args) {
        System.out.println("Hello world!");
    }
}

यदि आप संकलन करते हैं और फिर उपरोक्त कक्षाएं चलाने का प्रयास करते हैं, तो आपको एक त्रुटि मिलेगी:

$ javac com/example/*.java
$ java com.example.Test
Error: Main method not found in class test.Test, please define the main method as:
   public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application

Test क्लास के लिए कोड को देखने वाला कोई व्यक्ति main की घोषणा को देखेगा और उसके हस्ताक्षर को देखेगा और सोच सकता है कि java कमांड के बारे में क्या शिकायत है। लेकिन वास्तव में, java कमान सच कह रही है।

जब हम Test के समान पैकेज में String एक संस्करण की घोषणा करते हैं, तो यह संस्करण java.lang.String के स्वचालित आयात पर पूर्वता लेता है। इस प्रकार, Test.main विधि का हस्ताक्षर वास्तव में है

void main(com.example.String[] args) 

के बजाय

void main(java.lang.String[] args)

और java आदेश एक entrypoint पद्धति के रूप में है कि पहचान नहीं होंगे।

सबक: कक्षाओं में मौजूदा वर्ग के रूप में एक ही नाम है कि परिभाषित नहीं करते java.lang , या जावा SE पुस्तकालय में अन्य आमतौर पर इस्तेमाल किया कक्षाओं। यदि आप ऐसा करते हैं, तो आप अपने आप को सभी प्रकार की अस्पष्ट त्रुटियों के लिए खोल रहे हैं।

एक बूलियन का परीक्षण करने के लिए '==' का उपयोग करना

कभी-कभी एक नया जावा प्रोग्रामर इस तरह कोड लिखेगा:

public void check(boolean ok) {
    if (ok == true) {           // Note 'ok == true'
        System.out.println("It is OK");
    }
}

एक अनुभवी प्रोग्रामर हाजिर होगा कि अनाड़ी होने के नाते वह इसे फिर से लिखना चाहेगा:

public void check(boolean ok) {
    if (ok) {
       System.out.println("It is OK");
    }
}

हालांकि, साधारण अनाड़ीपन की तुलना में ok == true साथ अधिक गलत है। इस भिन्नता पर विचार करें:

public void check(boolean ok) {
    if (ok = true) {           // Oooops!
        System.out.println("It is OK");
    }
}

यहाँ प्रोग्रामर ने गलत तरीके से == as = ... लिखा है और अब कोड में एक सूक्ष्म बग है। x = true अनकंडिशनल true से x को true असाइन करता true और फिर true मूल्यांकन करता true । दूसरे शब्दों में, check विधि अब "यह ठीक है" प्रिंट करेगी चाहे कोई भी पैरामीटर हो।

यहाँ पाठ का उपयोग करने की आदत से बाहर निकलना है == false और == true । क्रियात्मक होने के अलावा, वे आपके कोडिंग को अधिक त्रुटि प्रवण बनाते हैं।


नोट: ok == true एक संभावित विकल्प जो कि गड्ढे से बचता है वह है योदा की स्थिति का उपयोग करना; यानी संबंधवाचक संचालक के बाईं ओर शाब्दिक, जैसा कि true == ok । यह काम करता है, लेकिन अधिकांश प्रोग्रामर शायद सहमत होंगे कि योदा की स्थिति विषम दिखती है। निश्चित रूप से ok (या !ok ) अधिक संक्षिप्त और अधिक प्राकृतिक है।

नुकसान - वाइल्डकार्ड आयात आपके कोड को नाजुक बना सकते हैं

निम्नलिखित आंशिक उदाहरण पर विचार करें:

import com.example.somelib.*;
import com.acme.otherlib.*;

public class Test {
    private Context x = new Context();   // from com.example.somelib
    ...
}

मान लीजिए जब जब आप पहली बार के संस्करण 1.0 के खिलाफ कोड विकसित कि somelib और के 1.0 संस्करण otherlib । फिर कुछ बाद के बिंदु पर, आपको अपनी निर्भरता को बाद के संस्करणों में अपग्रेड करने की आवश्यकता है, और आप otherlib संस्करण 2.0 का उपयोग करने का निर्णय लेते हैं। इसके अलावा लगता है परिवर्तन है कि वे करने के लिए किया है कि एक otherlib 1.0 और 2.0 के बीच एक जोड़ने के लिए था Context वर्ग।

अब जब आप Test फिर से शुरू करते हैं, तो आपको एक संकलन त्रुटि मिलेगी जो आपको Context कि Context एक अस्पष्ट आयात है।

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

यहां समस्या वाइल्डकार्ड आयात की है। एक ओर, वाइल्डकार्ड का उपयोग करने से आपकी कक्षाएं कुछ पंक्तियों को छोटा कर सकती हैं। दूसरी ओर:

  • अपने मानक कोड के अन्य भागों में जावा मानक पुस्तकालयों या तीसरे पक्ष के पुस्तकालयों के लिए संगत बदलावों के कारण संकलन त्रुटियां हो सकती हैं।

  • पठनीयता ग्रस्त है। जब तक आप एक आईडीई का उपयोग नहीं कर रहे हैं, तब तक यह पता लगाना कि वाइल्डकार्ड आयात में से कौन सा नामित वर्ग में खींच रहा है, मुश्किल हो सकता है।

सबक यह है कि कोड में वाइल्डकार्ड आयात का उपयोग करना एक बुरा विचार है जिसे लंबे समय तक रहने की आवश्यकता है। विशिष्ट (गैर-वाइल्डकार्ड) आयात एक IDE का उपयोग करने के लिए बनाए रखने के लिए बहुत प्रयास नहीं हैं, और प्रयास सार्थक है।

नुकसान: तर्क या उपयोगकर्ता इनपुट सत्यापन के लिए 'जोर' का उपयोग करना

एक सवाल जो कभी-कभी StackOverflow पर होता है, क्या यह विधि द्वारा आपूर्ति की गई तर्कों को मान्य करने के लिए assert का उपयोग करना उचित है, या उपयोगकर्ता द्वारा प्रदान किए गए इनपुट भी।

सरल उत्तर यह है कि यह उचित नहीं है।

बेहतर विकल्पों में शामिल हैं:

  • कस्टम कोड का उपयोग करके एक अवैध अतिक्रमण अपवाद को फेंकना।
  • Google अमरूद पुस्तकालय में उपलब्ध Preconditions विधियों का उपयोग करना।
  • का प्रयोग Validate तरीकों अपाचे कॉमन्स Lang3 पुस्तकालय में उपलब्ध।

यह जावा भाषा विशिष्टता (जावा 8 के लिए JLS 14.10), इस मामले पर सलाह देती है:

आमतौर पर, कार्यक्रम के विकास और परीक्षण के दौरान दावे की जाँच सक्षम की जाती है, और प्रदर्शन में सुधार के लिए तैनाती के लिए अक्षम किया जाता है।

क्योंकि दावे को अक्षम किया जा सकता है, कार्यक्रमों को यह नहीं मानना चाहिए कि अभिकथन में निहित अभिव्यक्तियों का मूल्यांकन किया जाएगा। इस प्रकार, इन बूलियन अभिव्यक्तियों को आम तौर पर दुष्प्रभावों से मुक्त होना चाहिए। मूल्यांकन के पूरा होने के बाद दिखाई देने वाली किसी भी स्थिति को ऐसे बूलियन अभिव्यक्ति का मूल्यांकन नहीं करना चाहिए। यह एक बूलियन अभिव्यक्ति के लिए एक पक्ष प्रभाव में निहित करने के लिए अवैध नहीं है, लेकिन यह आमतौर पर अनुचित है, क्योंकि यह इस बात के आधार पर कार्यक्रम के व्यवहार को भिन्न कर सकता है कि क्या दावे सक्षम या अक्षम थे।

इसके प्रकाश में, सार्वजनिक विधियों में तर्क जाँच के लिए अभिकथन का उपयोग नहीं किया जाना चाहिए। तर्क की जाँच आम तौर पर एक विधि के अनुबंध का हिस्सा है, और इस अनुबंध को सुनिश्चित किया जाना चाहिए कि क्या दावे सक्षम या अक्षम हैं।

तर्क की जाँच के लिए अभिकथन का उपयोग करने के साथ एक माध्यमिक समस्या यह है कि गलत तर्कों को एक उपयुक्त रन-टाइम अपवाद (जैसे कि IllegalArgumentException , ArrayIndexOutOfBoundsException , या NullPointerException ) में परिणाम करना चाहिए। एक जोरदार विफलता एक उपयुक्त अपवाद नहीं फेंकेगी। फिर, सार्वजनिक तरीकों पर तर्क की जाँच के लिए दावे का उपयोग करना अवैध नहीं है, लेकिन यह आमतौर पर अनुचित है। यह दावा किया जाता है कि AssertionError कभी नहीं पकड़ी जा सकती है, लेकिन ऐसा करना संभव है, इस प्रकार, बयानों के लिए नियम, थ्रो स्टेटमेंट के वर्तमान उपचार के समान प्रयास ब्लॉक में प्रदर्शित होने वाले अभिकथन का इलाज करना चाहिए।

आदिमता में ऑटो-अनबॉक्सिंग नल ऑब्जेक्ट्स का नुकसान

public class Foobar {
    public static void main(String[] args) {

        // example: 
        Boolean ignore = null;
        if (ignore == false) {
            System.out.println("Do not ignore!");
        }
    }
}

यहाँ नुकसान यह है कि false की तुलना null है। जब से हम एक आदिम तुलना कर रहे हैं boolean एक के खिलाफ Boolean Unbox करने के लिए, जावा प्रयास Boolean Object एक आदिम बराबर में, तुलना के लिए तैयार है। हालाँकि, चूंकि यह मान null , इसलिए NullPointerException को फेंक दिया गया है।

जावा null मानों के खिलाफ आदिम प्रकार की तुलना करने में असमर्थ है, जो रनटाइम के दौरान NullPointerException कारण बनता है। हालत के आदिम मामले को false == null ; यह एक संकलन समय त्रुटि incomparable types: int and <null> उत्पन्न करेगा incomparable types: int and <null>



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow