TRUE का मूल्यांकन क्यों (i <= j && j <= i && i! = J) करता है?


104

मैंने जावा कोड का एक टुकड़ा लिखा है जो एक अनंत लूप में चल रहा है।

नीचे कोड है:

public class TestProgram {
    public static void main(String[] args){
        Integer i = new Integer(0);
        Integer j = new Integer(0);

        while(i<=j && j<=i && i!=j){
            System.out.println(i);
        }
    }
}

ऊपर दिए गए कोड में, whileलूप में स्थिति को देखते हुए , पहले ऐसा लगता है कि प्रोग्राम whileलूप के अंदर नहीं जाएगा । लेकिन वास्तव में यह एक अनंत लूप है और मूल्य को छापता रहता है।

यहाँ क्या हो रहा है?


8
सरल उत्तर i<=j && j<=i && i!=jयह स्थिति हमेशा सही का मूल्यांकन करती है। बस कागज का एक टुकड़ा ले लो और मूल्यांकन करें कि आप इसे पकड़ लेंगे :)
प्रदीप सिम्हा

4
जिस तरह से आप पूर्णांक बना रहे हैं वह गलत है। 'तुलना' का प्रयोग करें
nachokk

7
यदि आप कभी नहीं बदलते हैं iया j, आप पाश को समाप्त करने की उम्मीद कब करेंगे?
फ्रेड लार्सन

33
@PradeepSimha सरल अंतर मूल्यों के लिए, यह हमेशा गलत होगा । से i<=jऔर j<=iआप निष्कर्ष निकाल सकते हैं i == j, जो कि अंतिम शब्द का खंडन करता है। इस प्रकार पूरी अभिव्यक्ति झूठी का मूल्यांकन करती है और जबकि प्रवेश नहीं किया जाएगा। मुख्य बिंदु यहाँ वस्तु पहचान है!
सिरको

4
एक तरफ के रूप में, इस पुस्तक में 32 पहेली है जावा गूढ़ व्यक्ति: जाल, नुकसान, और कोने मामले।
Cyanfish

जवाबों:


188
  • i <= jकरने के लिए मूल्यांकन किया जाता है true, क्योंकि ऑटो unboxing पूर्णांक तुलना के लिए होता है और फिर दोनों iऔर jडिफ़ॉल्ट मान पकड़ 0

  • j <= itrueउपरोक्त कारण से मूल्यांकन किया जाता है ।

  • i != jकरने के लिए मूल्यांकन किया जाता है true, क्योंकि दोनों iऔर jविभिन्न वस्तुओं रहे हैं। और वस्तुओं की तुलना करते समय, ऑटो अनबॉक्सिंग की कोई आवश्यकता नहीं है।

सभी स्थितियां सत्य हैं, और आप बदल नहीं रहे हैं iऔर jलूप में हैं, इसलिए यह असीम रूप से चल रहा है।


10
क्या आप कृपया समझा सकते हैं, क्यों! = संदर्भ ऑब्जेक्ट्स के मेमोरी इंडेक्स के लिए जाँच कर रहा है और <= इंटेगर के अन-बॉक्सिंग मूल्य के लिए जाँच कर रहा है ?? .. इन ऑपरेटर के बीच ऐसा अंतर क्यों है?
पुनीत राज

41
@PunithRaj <&> ऑपरेटर प्राइमेटीज़ पर काम करते हैं न कि वस्तुओं पर, इसलिए इन ऑपरेटरों के लिए ऑटो अनबॉक्सिंग होता है। लेकिन == और! = ऑपरेटरों का उपयोग वस्तुओं की तुलना के लिए किया जा सकता है, इसलिए यहाँ unboxing की कोई आवश्यकता नहीं है, इसलिए वस्तुओं की तुलना की जाती है।
जुन्न अहसन

14
आह, निहित बॉक्सिंग / अनबॉक्सिंग के छिपे हुए खतरे !!
हॉट लिप्स

3
स्टैक ओवरफ्लो को सिर्फ एक नया टैग जोड़ना चाहिए, "जावा में ऑटो-अनबॉक्सिंग सबसे बड़ी गलती थी"। :-)। जावा गूढ़ पुस्तकों के लेखकों को छोड़कर। इसका उपयोग इन जैसे प्रश्नों को टैग करने के लिए करें।
user949300

4
ध्यान दें कि Integer.valueOf(0) == Integer.valueOf(0)हमेशा सच करने के लिए मूल्यांकन किया जाता है क्योंकि इस मामले में एक ही वस्तु दिया जाता है (IntegerCache देख grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/... )
विटाली Fedorenko

40

क्योंकि आप तुलना कर रहे हैं

  • 0 < = 0 (true) // unboxing

  • 0 > = 0 (true) // unboxing

  • reference != secondReference (true)जैसा कि आप वस्तुओं का निर्माण कर रहे हैं, न कि एक आदिम तुलना। अतः इसका मूल्यांकन करता है while(true) { // Never ending loop }


2
ओह! ऑटो UNBOXING के छिपे हुए ड्रैगन ... अच्छा स्पष्टीकरण।
HybrisHelp

17

पूर्णांक ऑब्जेक्ट अलग हैं। यह मूल int प्रकार से अलग है।

इस उत्तर को देखें: जावा में दो इंटेगर की तुलना कैसे करें?

i != jभाग सच है जो आप गलत उम्मीद कर रहे थे है।


जबकि सच है, यह यहाँ कोई फर्क नहीं पड़ता और न ही यह सवाल का जवाब देता है।
कोन

6
@Kon: वास्तव में यह जवाब है। trueऑटोबॉक्सिंग के कारण स्थितियां # 1 और # 2 का मूल्यांकन करती हैं । # 3 के मामले में ऑटोबॉक्सिंग लागू नहीं होता है और तुलना वस्तु (मेमोरी लोकेशन) स्तर पर होती है।
घर में

1

लूप समाप्त नहीं हो रहा है क्योंकि आपकी स्थिति सत्य है (i! = J सत्य है क्योंकि 2 अलग-अलग ऑब्जेक्ट हैं, इसके बजाय Integer.valueOf का उपयोग करें) और लूप के अंदर मान नहीं बदल रहे हैं इसलिए आपकी स्थिति हमेशा के लिए सही रहती है।


1

पूर्णांक ऑब्जेक्ट अलग हैं। यह मूल int प्रकार से अलग है। तो आप बस ऐसा ही कर सकते हैं। आप जो करते हैं, वह सिर्फ वस्तु की तुलना करता है और निश्चित रूप से परिणाम सत्य है।


1

दो अलग-अलग मामले हैं जिन्हें हमें पहले समझना होगा,

मामला एक:

        Integer i = new Integer(10);
        Integer j = new Integer(10);

        System.out.println((i<=j && j<=i && i!=j));
        System.out.println(i!=j);

मामला 2:

        Integer i = 10;
        Integer j = 10;

        System.out.println((i<=j && j<=i && i==j));
        System.out.println(i==j);

दोनों अलग हैं, के रूप में

मामले 1: i!=jहो जाएगा trueक्योंकि दोनों ढेर में दो अलग अलग वस्तु को संदर्भित और एक ही नहीं हो सकता। परंतु

मामले में 2: i==jहोगा trueक्योंकि दोनों 10 पूर्णांक शाब्दिक हैं और जावा बनाए रखता है pool for Integer literalsजिनका मूल्य है (-128 <= X <= 127)। तो, इस मामले में 10 <= 127 परिणाम सच हैं, इसलिए दोनों में एक ही वस्तु का संदर्भ होगा।


0

शायद इसका कारण यह है कि 'मैं' और 'जे' दोनों वस्तुएं हैं, और वस्तु तुलना वस्तु संदर्भ तुलना के समान नहीं है। कृपया का उपयोग करने पर विचार करें! I.equals (j) के बजाय i! = J


0

कार्यक्रम का एक ही मूल्य प्रदर्शित करने पर रहता है iक्योंकि आप incrementing या decrementing या तो का मान नहीं कर रहे हैं iया j। के लिए स्थिति हमेशा सच का मूल्यांकन करती रहती है, इसलिए यह एक अनंत लूप है।


मुझे लगता है कि सवाल उस i!=jहिस्से के बारे में अधिक था जो आश्चर्यजनक रूप से सच का मूल्यांकन करता है न कि <=तुलनाओं का।
सोरवक्स

0

इंटेगर ए = नया इंटेगर (0); Integer b = new Integer (0);

<= और> = तुलनाएं अनबॉक्स्ड मान 0 का उपयोग करेंगी, जबकि! = संदर्भों की तुलना करेंगे और सफल होंगे क्योंकि वे अलग-अलग ऑब्जेक्ट हैं।

यहां तक ​​कि यह भी i, e काम करेगा

इंटेगर ए = 1000; इंटेगर बी = 1000;

लेकिन यह नहीं है:

पूर्णांक = 100; इंटेगर बी = 100;

इसका कारण यह है कि इंटेगर आंतरिक रूप से -128 और 127 के बीच इंटेगर ऑब्जेक्ट्स के लिए कैशिंग का उपयोग करता है और उस कैश से रिटर्न के उदाहरणों को शामिल करता है, जो इसे कवर करता है। मुझे यकीन नहीं है लेकिन मुझे लगता है कि आप पैकेज "java.lang.Integer.IntegerCache.high" में इसका अधिकतम मूल्य भी बदल सकते हैं।

बेहतर समझ के लिए url देखें: https://www.owasp.org/index.php/Java_gotchas#Immutable_Objects_.2F_Wrapper_Class_Caching


-3

आपको && इस और इसे & में थोड़ा भिन्न जानना होगा और जब आप && का उपयोग करते हैं और तब जब पहली शर्त सत्य होती है, तो यह दूसरी स्थिति की जाँच करता है यदि इसकी झूठी है तो उसने तीसरी स्थिति नहीं जाँची है क्योंकि & ऑपरेटर में यदि एक स्थिति झूठी है बयान गलत है अगर उपयोग करें || तब यदि यह सत्य दिखाई देता है तो यह आपके कोड में सत्य है क्योंकि i और j बराबर है पहली और दूसरी स्थिति सत्य है तो तीसरी स्थिति में यह झूठी होगी क्योंकि वे समान हैं और जबकि स्थिति झूठी है।


मैं क्यों मेरा उत्तर खानों मूल्य मिलता है क्योंकि मेरा उत्तर सच इस लिंक को देख रहा है पता नहीं है अपने असली तो इससे पहले कि मेरे जवाब देने के लिए खानों को पढ़ पाने के अधिक stackoverflow.com/questions/5564410/difference-between-and
सारा Sodagari
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.