Въпрос относно идентичността на обекта и равенството на обекта и изключение от клас String

Това е въпрос за Java и C#. Всички знаем, че Object Identity(==) тества дали два обекта се отнасят за едно и също местоположение, а Obejct Equality(Equals method) тества дали два различни (неидентични) обекта имат една и съща стойност. Но в случай на низов обект Object Identity и Равенството на обектите е същото. Например по-долу два булеви израза в операторите if връщат true

string a="123";
string b="123";
if(a==b)
if(a.Equals(b))

Защо е така?? Каква е рационалната основа зад това дизайнерско решение?


person Srinivas Reddy Thatiparthy    schedule 01.12.2009    source източник
comment
Предлагам ви да прочетете кода за Object.equals() и String.equals() и ще видите, че това не е правилно.   -  person Peter Lawrey    schedule 01.12.2009
comment
В C# == НЕ се счита за тест за ИДЕНТИЧНОСТ. Обикновено се прилага, за да прави всичко, което прави методът EQUALS на даден клас. ReferenceEquals(a, b) е тестът за ИДЕНТИЧНОСТ на .Net.   -  person ToolmakerSteve    schedule 26.09.2013


Отговори (4)


Java и C# използват техника за пестене на памет, наречена интерниране на низове. Тъй като низовете са неизменни в тези езици, те могат да обединяват често използвани низове (включени твърдо кодирани низови литерали, както във вашия пример) и да използват множество препратки към този низ в паметта, за да спестят място.

person Adam Maras    schedule 01.12.2009

Доколкото знам, в .net операторът == за низове е претоварен, за да използва Equals() вместо идентичност на обекта. Вижте това обяснение за подробности: http://www.dotnetperls.com/string-equals

Защото, ако трябва да знаете дали наистина е един и същ обект, използвайте това:

Object.ReferenceEquals(string1, string2)
person Ralf    schedule 21.07.2011

Всъщност, поне в Java, има механизъм за кеширане на низове. Клопка е, че два низа, които са еднакви, понякога, но не винаги ще върнат истина при прилагане на оператора за идентичност. следният код отпечатва невярно:

String a="123";
String b="12";
b=b+"3";
System.out.println(a==b);
person Buhb    schedule 01.12.2009

Ако наистина искате да сте сигурни, че a.equals(b) == true, но (a==b) == false се оценява на false за два низа a и b, тогава можете да използвате напълно подценения (^^) конструктор на низове:

String a = new String("abc");
String b = new String("abc");
if (a.equals(b)) {
   doTheyAreEqual();
   if (a != b) {
     doButNotTheSame();
   }
}
person Andreas Dolk    schedule 01.12.2009
comment
В C# и двете ще бъдат оценени като „вярно“. ReferenceEquals(a, b) ще даде оценка на „false“. - person ToolmakerSteve; 27.09.2013