Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Строки Java: Введение в ООП

Среди встроенных в Java типов данных, строки стоят особняком. У них настолько необычное поведение, что его нужно разбирать отдельно. Строки это объекты класса java.lang.String, а не примитивные значения, как можно было бы подумать. Но они существуют в двух формах для производительности. Иногда строки ведут себя как примитивные значения, иногда как объекты.

Зачем строки сделаны объектами? По двум причинам. У строк много полезного поведения, которое удобно реализовать в виде методов. Строки имеют непостоянную длину, по техническим причинам, такие данные внутри памяти хранятся не как примитивные объекты.

Строки как объекты:

// Такой способ работы называется String Literal
// Когда строка создается из литерала, специального
// синтаксиса для создания строки (текст обрамленный кавычками)
var name1 = "Hexlet";
name1.toUpperCase(); // "HEXLET"

// Этот способ называется String Object
var name2 = new String("Hexlet");
// Тут то же самое
name2.toUpperCase(); // "HEXLET"

С другой стороны, если мы попытаемся сравнить две строки, то получим неожиданный результат:

var name1 = "Hexlet";
var name2 = "Hexlet";

name1 == name2; // true

По логике, описанной в этом уроке, два создания строки должны приводить к созданию двум разным объектам, которые имеют разные ссылки. В случае строк все хитрее из-за требований к производительности. В реальных приложениях строки создаются в больших количествах на каждом шагу. Постоянное создание новых объектов приводило бы к огромному расходу памяти. Разработчики Java схитрили. Если строка создается как String Literal, то объект создается только при первом появлении такого значения строки. Второе и последющие создания строки с уже существующим значением будут ссылаться на ту первую строку:

// Внутри JVM создается объект
var lang1 = "Java";
//
// "Java" уже была, поэтому объект не создаем
// ссылаемся на уже созданный ранее
var lang2 = "Java";
// Тоже ссылка на первую строку
var lang3 = "Java";

lang1 == lang2; // true
lang2 == lang3; // true
lang1 == lang3; // true

Но если строки созданы как объекты, например через new String(), то они будут сравниваться по стандартной схеме:

var lang1 = new String("Java");
var lang2 = new String("Java");

lang1 == lang2; // false

Логично, но неудобно. В реальном коде сравнивать строки по ссылкам бесмысленно, строки сравнивают по значению. Программисты, в своем коде редко создают строки как объекты и, казалось бы проблемы нет. Если использовать String Literal, то все будет хорошо. К сожалению эта логика не работает, Java много где выполняет автоматическое преобразование String Literal в String Object:

var lang = "Java";

lang.toUpperCase(); // "JAVA"
lang.toUpperCase(); // "JAVA"

// Казалось бы одинаковые значения
// А теперь сравним

lang.toUpperCase() == lang.toUpperCase(); // false

Вот это уже проблема. И она настолько важная, что в строки встроили метод equals, который сравнивает их по значению независимо ни от чего:

var lang1 = new String("Java");
var lang2 = new String("Java");

lang1.equals(lang2); // true

Общее правило звучит так. Если у нас нет цели сравнивать ссылки, то всегда используем метод equals(), так мы защитимся от случайных ошибок преобразования типов.


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Java-разработчик
Профессия
Разработка приложений на языке Java
30 июня 10 месяцев

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Изображение Тото

Задавайте вопросы, если хотите обсудить теорию или упражнения. Команда поддержки Хекслета и опытные участники сообщества помогут найти ответы и решить задачу