Sobes.tech
Middle
120
questionbank

Как строки хранятся в памяти в языке Java?

Ответ от нейросети

sobes.tech AI

В Java строка (String) является неизменяемым объектом. Ее значение представлено последовательностью символов.

До Java 9, String хранила символы в массиве char[]. Каждый символ занимал 2 байта (UTF-16).

// До Java 9
public final class String implements Serializable, Comparable<String>, CharSequence {
    private final char value[]; // Символы строки
    private final int offset;   // Начальное смещение
    private final int count;    // Количество символов (длина)
    // ... другие поля и методы
}

С Java 9, для экономии памяти, String может использовать либо массив byte[] (для ASCII/Latin-1 символов), либо массив char[] (для UTF-16 символов). Для определения кодировки используется флаг coder.

// С Java 9
public final class String implements Serializable, Comparable<String>, CharSequence {
    private final byte[] value; // Символы строки (byte[] или char[] по сути, в зависимости от coder)
    private final byte coder;   // Кодировка: 0 для Latin-1, 1 для UTF-16
    // ... другие поля и методы
}

Строковые литералы (допустимые символы) и строки, созданные с помощью оператора new String(...), хранятся на "куче" (heap).

Строковые литералы также помещаются в "пул строк" (String Pool), находящийся в области памяти PermGen (до Java 8) или MetaSpace (с Java 8). Если строка с таким значением уже существует в пуле, используется ссылка на существующий объект.

String s1 = "hello"; // Создает "hello" в String Pool (если нет), s1 ссылается на него
String s2 = "hello"; // s2 ссылается на тот же объект "hello" в String Pool
String s3 = new String("hello"); // Создает новый объект "hello" на куче, s3 ссылается на него. "hello" может быть в String Pool

Поскольку строки неизменяемы, изменение значения строки (например, конкатенация) приводит к созданию нового объекта String в памяти.