Как строки хранятся в памяти в языке 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 в памяти.