Зарегистрируйтесь, чтобы продолжить обучение

Строки 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 создается объект new String()
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(), так мы защитимся от случайных ошибок.


Дополнительные материалы

  1. Класс String, представляющий строки

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

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

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

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

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

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

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

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

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

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

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
от 25 000 ₸ в месяц
Разработка приложений на языке Java
10 месяцев
с нуля
Старт 26 декабря

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

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

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

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»