• ,

Ах, эти строки...

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

Вот о чем мы поговорим:

  • Устройство строки
  • Строковые литералы
  • Сравнение строк
  • Сложение строк
  • Выборка подстроки и копирующий конструктор
  • Изменение строки
  • Начнем с основ.

Устройство строки


Класс java.lang.String содержит в себе три поля:

/**
 * NOTE: This is just a partial API
 */
public final class String{

    private final char value[];
    private final int offset;
    private final int count;

}


На самом деле там содержатся и другие поля, например, hash-код, но сейчас это неважно. Основные – эти.

Итак, в основе строки лежит массив символов (char). При хранении символов в памяти используется кодировка Unicode UTF-16BE. Подробнее о ней можно почитать тут. Начиная с версии Java 5.0 введена поддержка Unicode версии выше 2 и, соответственно, символов с кодами больше 0xFFFF. Для этих символов используются уже не один char, а два, подробнее о кодировке этих символов в той же статье.

Хоть поддержка этих символов и введена, да вот незадача – отобразить их не получится. Я нашел набор музыкальных символов (U1D100) и попробовал вывести хоть куда-нибудь скрипичный ключ (символ с кодом 1D120). Перевел код в два char, как и положено – '\uD834' и '\uDD20'. Декодер на них не ругается, честно распознает как один символ. Вот только шрифта нет, в котором этот символ существует. А потому – квадратик. И судя по всему – это надолго. Так что введение поддержки Unicode 4 можно рассматривать исключительно через призму задела на будущее.

Пойдем дальше. Я прошу обратить пристальное внимание на второе и третье поля – offset и count. Казалось бы, массив полностью определяет строку, если используются ВСЕ символы. Если же существуют такие поля – символы в массиве могут использоваться не все. Так оно и есть, об этом мы поговорим в части выборка подстроки и копирующий конструктор.