2009-07-29 10 views
164

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

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

+1

यदि आप अनिश्चित हैं, तो आप कोड, या जावाडोक पढ़ सकते हैं। बीटीडब्ल्यू अगर आप परीक्षण करना चाहते हैं तो वे वही ऑब्जेक्ट हैं जो आप assertSame का उपयोग कर सकते हैं। –

+2

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

उत्तर

226

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

जुनीट .equals() विधि assertEquals(Object o1, Object o2) विधि में समानता निर्धारित करने के लिए .equals() विधि को कॉल करता है।

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

Here is a link to a great Stackoverflow question== और .equals() के बीच मतभेद के कुछ के बारे में।

+11

आईआईआरसी assertEquals() सफल होता है अगर दोनों स्ट्रिंग शून्य हैं। यदि यह वही नहीं है जो आप चाहते हैं तो assertNotNull() को भी कॉल करें। – finnw

+0

@finnw, स्रोत की जांच, आप वास्तव में सही हैं। –

+10

इसके अतिरिक्त, यदि आप == के लिए परीक्षण करना चाहते हैं, तो आप assertSame() – james

3

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

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

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

1

"== ऑपरेटर चेकों दो Objects कर रहे हैं ठीक उसी Object को देखने के लिए।"

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

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

3
public class StringEqualityTest extends TestCase { 
    public void testEquality() throws Exception { 
     String a = "abcde"; 
     String b = new String(a); 
     assertTrue(a.equals(b)); 
     assertFalse(a == b); 
     assertEquals(a, b); 
    } 
} 
2

JUnit assertEquals(obj1, obj2) वास्तव में obj1.equals(obj2) फोन करता है।

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

तो आप ठीक हैं।

4

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

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

+0

अंगूठे ऊपर, वास्तव में स्ट्रिंग का मान है जिसे आप तुलना करना चाहते हैं या स्मृति स्थान का मान – Pomagranite

26

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

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

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

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

+0

"यही है, एक == बी यह देखने के लिए जांचता है कि ए और बी एक ही वस्तु हैं या नहीं।" तकनीकी रूप से यह यह जांचता है कि ए और बी एक ही ऑब्जेक्ट को संदर्भित करता है, क्योंकि ए और बी संदर्भ हैं। जब तक मैं बहुत गलत नहीं हूं। – andy

+0

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

संबंधित मुद्दे