Sobes.tech
Middle

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

sobes.tech AI

Отговор от 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[]; // Символи на низa
    private final int offset;   // Начален отместване
    private final int count;    // Брой символи (дължина)
    // ... други полета и методи
}

От Java 9 нататък, за икономия на памет, String може да използва или масив byte[] (за ASCII/Latin-1 символи), или масив char[]. Кодировката се определя от флага coder.

// От Java 9
public final class String implements Serializable, Comparable<String>, CharSequence {
    private final byte[] value; // Символи на низa (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 в паметта.