Зарегистрируйтесь для доступа к 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(), так мы защитимся от случайных ошибок преобразования типов.


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

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

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

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

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

Об обучении на Хекслете

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

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

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

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

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

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

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

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

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

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

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

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