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

Это вопрос по Java и С#. Мы все знаем, что Object Identity (==) проверяет, относятся ли два объекта к одному и тому же местоположению, а Obejct Equality (метод Equals) проверяет, имеют ли два разных (не идентичных) объекта одинаковое значение. Но в случае строкового объекта 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# == НЕ считается проверкой IDENTITY. Обычно он реализуется так, чтобы делать то, что делает метод EQUALS класса. ReferenceEquals(a, b) — это тест IDENTITY .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 есть механизм кэширования строк. Ловушка заключается в том, что две равные строки иногда, но не всегда, возвращают true при применении оператора идентификации. следующий код выводит false:

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) оценивается как «ложь». - person ToolmakerSteve; 27.09.2013