هو طريقة assertEquals جاوة موثوقة؟
سؤال
وأنا أعلم أن ==
لديه بعض المشكلات عند المقارنة بين اثنين من Strings
. يبدو أنه لا String.equals()
نهج أفضل. حسنا، أنا أفعل اختبار أداة JUnit وبلدي الميل لاستخدام assertEquals(str1, str2)
. هل هذه طريقة يمكن الاعتماد عليها لتأكيد اثنين من سلاسل تحتوي على نفس المضمون؟ وأود أن استخدام assertTrue(str1.equals(str2))
، ولكن بعد ذلك كنت لا تحصل على الاستفادة من رؤية ما هي القيم المتوقعة والفعلية على الفشل.
وعلى صعيد ذات صلة، هل لديها رابط إلى صفحة أو موضوع ما يفسر بوضوح المشاكل مع str1 == str2
؟
المحلول
ويجب عليك على دائما استخدام .equals()
عند مقارنة Strings
في جاوة.
وأداة JUnit استدعاء الأسلوب .equals()
لتحديد المساواة في assertEquals(Object o1, Object o2)
الأسلوب.
وهكذا، أنت آمن بالتأكيد باستخدام assertEquals(string1, string2)
. (لأن String
s هي Object
s)
هنا هو ارتباط إلى سؤال ستاكوفيرفلوو كبير و> بخصوص بعض الاختلافات بين ==
و.equals()
.
نصائح أخرى
وassertEquals
يستخدم الأسلوب equals
للمقارنة. هناك ASSERT مختلفة، assertSame
، والذي يستخدم المشغل ==
.
لنفهم لماذا ==
لا ينبغي أن تستخدم مع سلاسل تحتاج إلى فهم ما ==
به: أنه لا تحقق من هويته. وهذا هو، الشيكات a == b
لمعرفة ما إذا a
وb
تشير إلى <م> نفس الكائن م>. أنها بنيت في اللغة، ولا يمكن تغيير سلوكها من قبل فئات مختلفة. طريقة equals
، من ناحية أخرى، يمكن أن يتم تجاوز من قبل الطبقات. بينما السلوك الافتراضي الخاص به (في فئة Object
) هو أن تفعل عملية التحقق من الهوية باستخدام مشغل ==
، العديد من الفئات، بما في ذلك String
، تجاوز ذلك إلى القيام بدلا من ذلك "التكافؤ" الاختيار. في حالة String
، بدلا من التحقق إذا a
وb
الرجوع إلى نفس الكائن، والشيكات a.equals(b)
لمعرفة ما إذا كانت الأشياء التي تشير إلى كلاهما السلاسل التي تحتوي على بالضبط الأحرف نفسها.
ووقت القياس: تخيل أن كل كائن String
هو قطعة من الورق مع شيء مكتوب عليها. دعنا نقول لدي قطعتين من الورق مع "فو" مكتوب عليها، وآخر مع "بار" مكتوب عليها. إذا كنت تأخذ قطعتين الأولى من الورق واستخدام ==
لمقارنتها فإنه سيعود false
لأنه يسأل أساسا "هل هذه نفس قطعة من الورق؟". وهو ليس في حاجة للنظر حتى في ما هو مكتوب على الورق. والحقيقة أنني يعطيها قطعتين من الورق (بدلا من نفس واحدة مرتين) يعني أنه سيعود false
. إذا كنت تستخدم equals
، ومع ذلك، فإن طريقة equals
قراءة قطعتين من الورق ونرى أن يقولون الشيء نفسه ( "فو")، وذلك سوف يعود true
.
وبت أن يحصل الخلط مع سلاسل هو أن جافا لديه مفهوم "interning" سلاسل، وهذا هو (فعال) تنفيذ تلقائيا على أي سلسلة حرفية في التعليمات البرمجية. هذا يعني أنه إذا كان لديك اثنين من سلسلة حرفية تعادل في التعليمات البرمجية (حتى لو انهم في فئات مختلفة) أنها سوف فعلا كلاهما يشيران إلى نفس الكائن String
. وهذا يجعل المشغل ==
عودة true
في كثير من الأحيان مما قد يتوقع المرء.
في وباختصار يمكن القول - هل يمكن أن يكون كائنين التي تحتوي على سلسلة الأحرف نفسها بل هي كائنات مختلفة (في مواقع الذاكرة مختلفة). الشيكات المشغل == أن نرى أن مرجعين يشيران إلى نفس الكائن (ذاكرة المكان)، ولكن يساوي () الشيكات الطريقة إذا الأحرف هي نفسها.
وعادة ما كنت ترغب في التحقق إذا تحتوي على اثنين من سلاسل الأحرف نفسها، وليس ما إذا كانت تشير إلى نفس موقع الذاكرة.
نعم، يتم استخدامه في كل وقت للاختبار. فمن المحتمل جدا أن يستخدم إطار اختبار .equals () للمقارنات كهذه.
وفيما يلي رابط لشرح "سلسلة المساواة خطأ". أساسا، السلاسل في جافا هي كائنات، وعند مقارنة المساواة وجوه، وعادة ما تتم مقارنة تقوم على عنوان الذاكرة، وليس المحتوى. وبسبب هذا، وسلسلتين لا تحتل نفس العنوان، حتى لو كان مضمونها مطابق، ولذلك سوف لا تتطابق بشكل صحيح، على الرغم من أنها تبدو متشابهة عند الطباعة.
HTTP: //blog.enrii. كوم / 2006/03/15 / جافا سلسلة المساواة بين مشترك على خطأ /
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);
}
}
ووassertEquals(obj1, obj2)
أداة JUnit يدعو بالفعل obj1.equals(obj2)
.
وهناك أيضا assertSame(obj1, obj2)
التي لا obj1 == obj2
(أي، يتحقق من أن obj1
وobj2
يتم الرجوع إلى <م> نفس م> سبيل المثال)، وهذا ما كنت تحاول تجنب.
وهكذا أنت بخير.
و"المشغل ==
يتحقق لمعرفة ما إذا كان اثنين Objects
هي نفسها تماما Object
."
http://leepoint.net/notes-java/data/strings /12stringcomparison.html
وString
هو Object
في جافا، لذلك يقع ضمن هذه الفئة من القواعد المقارنة.