क्या जावा का अभिकथन विधि विश्वसनीय है?


199

मुझे पता है कि ==दो की तुलना करते समय कुछ मुद्दे हैं Strings। ऐसा लगता है कि String.equals()यह एक बेहतर तरीका है। खैर, मैं JUnit परीक्षण कर रहा हूं और मेरा झुकाव उपयोग करना है assertEquals(str1, str2)। क्या यह दो स्ट्रिंग्स को समान करने के लिए एक समान सामग्री है? मैं उपयोग करूंगा assertTrue(str1.equals(str2)), लेकिन तब आपको यह देखने का लाभ नहीं मिलेगा कि असफलता पर अपेक्षित और वास्तविक मूल्य क्या हैं।

संबंधित नोट पर, क्या किसी के पास एक पृष्ठ या धागे का लिंक है जो स्पष्ट रूप से समस्याओं के बारे में बताता है str1 == str2?


1
यदि आप अनिश्चित हैं, तो आप कोड, या Javadoc पढ़ सकते हैं। BTW यदि आप परीक्षण करना चाहते हैं तो वे एक ही वस्तु हैं जिसका आप उपयोग कर सकते हैं।
पीटर लॉरी 20

2
यदि str1 और str2 अशक्त हैं, तो AssertEquals () सत्य है, लेकिन assertTrue (str1.equals (str2)) एक अपवाद को फेंकता है। पहला उदाहरण एक उपयोगी त्रुटि संदेश भी प्रिंट करेगा जैसे कि str1 और str2 की सामग्री, दूसरा नहीं।
पीटर लॉरी

जवाबों:


274

जावा में तुलना करते समय आपको हमेशा उपयोग करना चाहिए ।.equals()Strings

JUnit ने कॉल किया .equals() विधि में समानता का निर्धारण करने के विधि कोassertEquals(Object o1, Object o2)

तो, आप निश्चित रूप से सुरक्षित हैं assertEquals(string1, string2)। (क्योंकि Stringएस हैंObject )

यहाँ कुछ के बीच अंतर के बारे में एक महान Stackoverflow सवाल का लिंक है== और .equals()


12
IIRC assertEquals () सफल होता है यदि दोनों तार अशक्त हैं। यदि यह वह नहीं है जो आप चाहते हैं तो assertNotNull () भी कॉल करें।
फाइन जुव 29'09

10
इसके साथ ही, यदि आप == के लिए परीक्षण करना चाहते हैं, तो आप assertSame () कॉल कर सकते हैं
जेम्स

7
मैं हमेशा नहीं कहूंगा ; कभी-कभी तार के लिए भी संदर्भ समानता वांछित है।
कारू

30

assertEqualsequalsतुलना के लिए विधि का उपयोग करता है । वहाँ एक अलग मुखर है assertSame, जो का उपयोग करता है== ऑपरेटर ।

यह समझने के लिए कि ==तार का उपयोग क्यों नहीं किया जाना चाहिए, आपको ==यह समझने की आवश्यकता है कि क्या होता है: यह एक पहचान की जाँच करता है। यही है, यह a == bदेखने के लिए जाँच करता है कि क्या aऔर उसी ऑब्जेक्टb को संदर्भित करता है । यह भाषा में बनाया गया है, और इसके व्यवहार को विभिन्न वर्गों द्वारा नहीं बदला जा सकता है। विधि, दूसरे हाथ पर, वर्गों द्वारा अधिरोहित जा सकता है। जबकि इसका डिफ़ॉल्ट व्यवहार ( कक्षा में) ऑपरेटर का उपयोग करके एक पहचान की जांच करना है , कई कक्षाएं, जिनमें से , इसे "समतुल्यता" चेक करने के लिए ओवरराइड करता है। के मामले में , जाँच के बजाय अगर और उसी वस्तु को देखें,equalsObject==StringStringaba.equals(b) यह देखने के लिए जांचें कि क्या वे जिन वस्तुओं को संदर्भित करते हैं, वे दोनों तार हैं जिनमें बिल्कुल समान वर्ण हैं।

सादृश्य समय: कल्पना करें कि प्रत्येक Stringवस्तु कागज का एक टुकड़ा है जिस पर कुछ लिखा गया है। मान लीजिए कि मेरे पास उन पर लिखे "फू" के साथ कागज के दो टुकड़े हैं, और दूसरे पर "बार" लिखा है। यदि मैं कागज के पहले दो टुकड़े लेता हूं और ==उनकी तुलना करने के लिए उपयोग करता हूं तो यह वापस आ जाएगा falseक्योंकि यह अनिवार्य रूप से पूछ रहा है "क्या ये कागज के एक ही टुकड़े हैं?"। यह भी देखने की जरूरत नहीं है कि कागज पर क्या लिखा है। तथ्य यह है कि मैं इसे कागज के दो टुकड़े दे रहा हूं (बल्कि एक ही बार दो बार) का मतलब है कि यह वापस आ जाएगा false। यदि मैं उपयोग करता हूं equals, हालांकि, equalsविधि कागज के दो टुकड़ों को पढ़ेगी और देखेगी कि वे एक ही बात कहते हैं ("फू"), और इसलिए यह वापस आ जाएगी true

स्ट्रिंग्स के साथ भ्रमित होने वाली बिट यह है कि जावा में "इंटर्निंग" स्ट्रिंग्स की एक अवधारणा है, और यह (प्रभावी रूप से) आपके कोड में किसी भी स्ट्रिंग शाब्दिक पर स्वचालित रूप से किया जाता है। इसका मतलब है कि यदि आपके पास अपने कोड में दो बराबर स्ट्रिंग शाब्दिक हैं (भले ही वे अलग-अलग कक्षाओं में हों) तो वे वास्तव में दोनों एक ही Stringवस्तु को संदर्भित करेंगे । यह ==ऑपरेटर trueको एक से अधिक बार वापसी की उम्मीद कर सकता है।


"यह है कि, a = b यह देखने के लिए जाँचता है कि क्या a और b समान वस्तु हैं।" तकनीकी रूप से यह जाँचता है कि क्या संदर्भ के लिए ए और बी एक ही वस्तु से संबंधित हैं, क्योंकि ए और बी संदर्भ हैं। जब तक मैं बहुत गलत नहीं हूँ।
बॉब

@ user1903064 जो सही है। चूंकि गैर-आदिम चर केवल जावा में संदर्भ हो सकते हैं, उनके बारे में बात करते समय अप्रत्यक्ष के अतिरिक्त स्तर को छोड़ना आम है, लेकिन मैं मानता हूं कि इस मामले में अधिक स्पष्ट होना फायदेमंद है। मैंने जवाब अपडेट कर दिया है। सलाह के लिये धन्यवाद!
लॉरेंस गोंसाल्वेस

7

संक्षेप में - आपके पास दो स्ट्रिंग ऑब्जेक्ट हो सकते हैं जिसमें समान वर्ण होते हैं लेकिन अलग-अलग ऑब्जेक्ट होते हैं (विभिन्न मेमोरी स्थानों में)। == ऑपरेटर यह देखने के लिए जाँच करता है कि दो संदर्भ एक ही वस्तु (मेमोरी लोकेशन) की ओर इशारा कर रहे हैं, लेकिन यदि वर्ण समान हैं तो बराबर () विधि जाँचती है।

आमतौर पर आप यह जांचने में रुचि रखते हैं कि क्या दो स्ट्रिंग्स में समान वर्ण हैं, न कि वे एक ही मेमोरी लोकेशन की ओर इशारा करते हैं।



3

हाँ, यह परीक्षण के लिए हर समय उपयोग किया जाता है। यह बहुत संभावना है कि परीक्षण रूपरेखा इन जैसे तुलना के लिए। (असमान) का उपयोग करता है।

नीचे एक लिंक "स्ट्रिंग समानता की गलती" के बारे में बताया गया है। अनिवार्य रूप से, जावा में तार वस्तुएं हैं, और जब आप वस्तु समानता की तुलना करते हैं, तो आमतौर पर उनकी तुलना स्मृति पते के आधार पर की जाती है, न कि सामग्री के आधार पर। इस वजह से, दो तार एक ही पते पर कब्जा नहीं करेंगे, भले ही उनकी सामग्री समान हो, इसलिए वे सही ढंग से मेल नहीं खाएंगे, भले ही वे मुद्रित होने पर समान दिखें।

http://blog.enrii.com/2006/03/15/java-string-equality-common-mistake/


3

JUnit assertEquals(obj1, obj2)वास्तव में कॉल करता है obj1.equals(obj2)

वहाँ भी है assertSame(obj1, obj2)जो करता है obj1 == obj2(यानी, कि पुष्टि करता है obj1और एक हीobj2 संदर्भित कर रहे हैं उदाहरण ), जो कि आप बचने की कोशिश कर रहे हैं।

तो तुम ठीक हो।


0

" ==ऑपरेटर यह देखने के लिए जांच करता है कि क्या दो Objectsसमान हैं Object।"

http://leepoint.net/notes-java/data/strings/12stringcomparison.html

Stringएक है Objectतो यह तुलना नियमों की है कि श्रेणी में आता है, जावा में।


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