Java: Введение в ООП
Теория: Строки
Среди встроенных в Java типов данных, строки стоят особняком. У них настолько необычное поведение, что его нужно разбирать отдельно. Строки — это объекты класса java.lang.String, а не примитивные значения, как можно было бы подумать. Но они существуют в двух формах для производительности. Иногда строки ведут себя как примитивные значения, иногда как объекты.
Зачем строки сделаны объектами? По двум причинам. У строк много полезного поведения, которое удобно реализовать в виде методов. Строки имеют непостоянную длину, по техническим причинам, такие данные внутри памяти хранятся не как примитивные объекты.
Строки как объекты:
С другой стороны, если мы попытаемся сравнить две строки, то получим неожиданный результат:
По логике, описанной в этом уроке, два создания строки должны приводить к созданию двух разных объектов с разными ссылками. В случае строк все хитрее из-за требований к производительности.
В реальных приложениях строки создаются в больших количествах на каждом шагу. Постоянное создание новых объектов приводило бы к огромному расходу памяти. Разработчики Java схитрили. Если строка создается как String Literal, то объект создается только при первом появлении такого значения строки. Второе и последующие создания строки с уже существующим значением будут ссылаться на ту первую строку:
Но если строки созданы как объекты сразу, например через new String(), то они будут сравниваться по стандартной схеме:
Логично, но неудобно. В реальном коде сравнивать строки по ссылкам бессмысленно, строки сравнивают по значению. Программисты, в своем коде редко создают строки как объекты и, казалось бы проблемы нет. Если использовать String Literal, то все будет хорошо. К сожалению, эта логика не работает, Java много где выполняет автоматическое преобразование String Literal в String Object:
Вот это уже проблема. И она настолько важная, что в строки встроили метод equals(), который сравнивает их по значению независимо ни от чего:
Общее правило звучит так. Если у нас нет цели сравнивать ссылки, то всегда используем метод equals(), так мы защитимся от случайных ошибок.

