बॉक्सिंग लॉन्ग वैल्यू 127 और 128 की तुलना करें


111

मैं शर्तों का उपयोग करके दो लंबी वस्तुओं के मूल्यों की तुलना करना चाहता हूं if। जब ये मान 128 से कम होते हैं , तो ifस्थिति ठीक से काम करती है, लेकिन जब वे 128 से अधिक या बराबर होते हैं , तो तुलना विफल हो जाती है।

उदाहरण:

Long num1 = 127;
Long num2 = 127;

if (num1 == num2) {
    // Works ok
}

उपरोक्त कोड पर तुलना ठीक से काम करती है, लेकिन नीचे दिए गए कोड में विफल रहती है:

Long num1 = 128;
Long num2 = 128;

if (num1 == num2) {
    // Does NOT work
}

127 से अधिक मूल्यों वाले लॉन्ग वेरिएबल्स की तुलना करने में समस्या क्यों है ? यदि वैरिएबल डेटा प्रकार को लंबे प्राइमेटिव में बदल दिया जाता है , तो तुलना सभी मामलों के लिए काम करती है।

जवाबों:


212

टी एल; डॉ

जावा कैश से पूर्णांक उदाहरणों बॉक्सिंग -128के लिए 127। चूंकि आप मानों के बजाय ==ऑब्जेक्ट संदर्भों की तुलना करने के लिए उपयोग कर रहे हैं , केवल कैश्ड ऑब्जेक्ट्स मेल खाएंगे। या तो अनबॉक्स्ड आदिम मूल्यों के साथ काम करें या अपनी वस्तुओं की तुलना करने के लिए उपयोग करें ।long.equals()Long

लम्बा (वाक्य का इरादा) संस्करण

127 से अधिक मूल्य वाले लॉन्ग वेरिएबल की तुलना करने में समस्या क्यों है? यदि उपरोक्त चर का डेटा प्रकार आदिम (लंबा) है, तो सभी मानों के लिए कोड काम करता है।

जावा कैश इंटेगर ऑब्जेक्ट्स की रेंज -128 से 127 तक है । ने कहा कि:

  • यदि आप एन लॉन्ग वैरिएबल को वैल्यू 127( कैश्ड ) पर सेट करते हैं , तो उसी ऑब्जेक्ट उदाहरण को सभी संदर्भों द्वारा इंगित किया जाएगा। (एन चर, 1 उदाहरण)
  • यदि आप एन लॉन्ग वैरिएबल को वैल्यू सेट करते हैं 128( कैश नहीं किया गया है ), तो आपके पास हर संदर्भ द्वारा इंगित ऑब्जेक्ट इंस्टेंस होगा। (एन चर, एन उदाहरण)

इसलिए यह है:

Long val1 = 127L;
Long val2 = 127L;

System.out.println(val1 == val2);

Long val3 = 128L;
Long val4 = 128L;

System.out.println(val3 == val4);

इसे आउटपुट करता है:

सच्चा
झूठा

के लिए 127L मूल्य, दोनों संदर्भों के बाद से (VAL1 और val2) बिंदु एक ही वस्तु उदाहरण के लिए स्मृति (कैश्ड) में, यह रिटर्नtrue

दूसरी ओर, 128 मान के लिए, क्योंकि इसके लिए कोई उदाहरण नहीं है, जो कि मेमोरी में कैश्ड है, बॉक्सिंग वैल्यू के लिए किसी भी नए असाइनमेंट के लिए एक नया बनाया जाता है, जिसके परिणामस्वरूप दो अलग-अलग इंस्टेंसेस (val3 और val4 द्वारा इंगित) और वापस आ रहे हैंfalse रहे हैं। उनके बीच तुलना।

ऐसा केवल इसलिए होता है क्योंकि आप ऑपरेटर के साथ दो Long ऑब्जेक्ट संदर्भों की तुलना कर रहे हैं , न कि longआदिम मूल्यों की ==। यदि यह इस कैश तंत्र के लिए नहीं था, तो ये तुलना हमेशा विफल रहेगी , इसलिए यहां वास्तविक समस्या ==ऑपरेटर के साथ बॉक्सिंग मूल्यों की तुलना है ।

इन चरों को आदिम longप्रकारों में बदलने से ऐसा होने से रोका जा सकेगा, लेकिन अगर आपको Longवस्तुओं का उपयोग करके अपना कोड रखने की आवश्यकता होती है , तो आप निम्नलिखित तरीकों से इन तुलनाओं को सुरक्षित रूप से कर सकते हैं:

System.out.println(val3.equals(val4));                     // true
System.out.println(val3.longValue() == val4.longValue());  // true
System.out.println((long)val3 == (long)val4);              // true

(कास्टिंग के लिए उचित अशक्त जाँच आवश्यक है)

IMO , ऑब्जेक्ट की तुलना करते समय असमान () तरीकों के साथ रहना हमेशा एक अच्छा विचार है ।

संदर्भ लिंक:


15

जावा -128 से 127 तक के आदिम मूल्यों को कैश करता है । जब हम दो लॉन्ग ऑब्जेक्ट्स जावा की तुलना करते हैं, तो आंतरिक रूप से इसे आदिम मान पर डालते हैं और इसकी तुलना करते हैं। लेकिन 127 से अधिक लंबी वस्तु को टाइप जाति नहीं मिलेगी। जावा .valueOf () विधि द्वारा आउटपुट को कैश करता है ।

यह कैशिंग बाइट, शॉर्ट, लॉन्ग से -128 से 127 तक के लिए काम करता है। इंटेगर कैशिंग से -128 से java.lang.Integer.IntegerCache.high या 127 के लिए काम करता है, जो भी बड़ा हो। (हम शीर्ष स्तर का मान सेट कर सकते हैं, जिसमें इंटेगर का मान होता है। java.lang.Integer.IntegerCache.high) का उपयोग करके कैश किया जाना चाहिए।

 For example:
    If we set java.lang.Integer.IntegerCache.high=500;
    then values from -128 to 500 will get cached and 

    Integer a=498;
    Integer b=499;
    System.out.println(a==b)

    Output will be "true".

फ्लोट और डबल ऑब्जेक्ट्स कभी भी कैश नहीं होते हैं।

कैरेक्टर को 0 से 127 तक कैश मिलेगा

आप दो वस्तुओं की तुलना कर रहे हैं। इसलिए == ऑपरेटर वस्तु संदर्भों की समानता की जांच करेगा। इसे करने के निम्नलिखित तरीके हैं।

1) दोनों वस्तुओं को आदिम मूल्यों में टाइप करें और तुलना करें

    (long)val3 == (long)val4

2) वस्तु का मूल्य पढ़ें और तुलना करें

    val3.longValue() == val4.longValue()

3) ऑब्जेक्ट तुलना पर बराबर () विधि का उपयोग करें।

    val3.equals(val4);  

14

num1और num2लंबी वस्तुएँ हैं। आपको equals()उनकी तुलना करने के लिए उपयोग करना चाहिए । ==तुलना कभी-कभी जेवीएम बॉक्स प्राइमेटिक्स के कारण काम कर सकती है, लेकिन इस पर निर्भर नहीं होती है।

if (num1.equals(num1))
{
 //code
}

1
यह (जो बेहतर है), या के वापसी मूल्य की तुलना करें .longValue()
गिउलिओ फ्रेंको

4

जावा में गैर-आदिम (उर्फ वस्तुओं) की ==तुलना उनके मूल्यों के बजाय उनके संदर्भ से की जाती है। Longएक वर्ग है और इस प्रकारLong मान ऑब्जेक्ट हैं।

समस्या यह है कि जावा डेवलपर्स चाहते थे कि लोग उपयोग करें Longजैसे कि वे longसंगतता प्रदान करते थे, जिससे longऑटोबॉक्सिंग की अवधारणा पैदा हुई, जो अनिवार्य रूप से विशेषता है, -विकास को बदल दिया जाएगाLong और आवश्यकतानुसार इसके विपरीत। ऑटोबॉक्सिंग का व्यवहार हर समय बिल्कुल अनुमानित नहीं है, हालांकि यह पूरी तरह से निर्दिष्ट नहीं है।

तो सुरक्षित होने के लिए और अनुमानित परिणाम हमेशा .equals()वस्तुओं की तुलना करने के लिए उपयोग करते हैं और इस मामले में ऑटोबॉक्सिंग पर भरोसा नहीं करते हैं:

Long num1 = 127, num2 = 127;
if(num1.equals(num2)) { iWillBeExecutedAlways(); }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.