Java: Почему постоянный пул поддерживается только для значений String?

Мой вопрос о java interning и постоянных пулах.

Java поддерживает пул констант для java.lang.String, умеет использовать JVM-память, и для этого java.lang.String становится неизменным. Итак, почему Java не поддерживает постоянные пулы других неизменяемых типов, таких как Long, Integer, Char, Short?. Не может ли это также сохранить память?

Мне известно, что целые числа объединены в диапазон значений [-127, 127], хотя я не понимаю причины выбора этого диапазона.

Вот тестовый код, который я написал для тестирования пула других неизменяемых типов данных.

public class PoolTest {

    public static void main(String... args) {

        // Pooling of Integer [-127, 127]
        Integer x = 127, y = 127;
        System.out.println("Integer:" + (x == y)); // prints true
        x = 129;
        y = 129;
        System.out.println("Integer:" + (x == y)); // prints false

        // Apparent pooling of short [-127, 127]
        Short i = 127, j = 127;
        System.out.println("Short: " + (i == j)); // prints true
        i = 128;
        j = 128;
        System.out.println("Short: " + (i == j)); // prints false

        // No pooling of long values
        Long k = 10L, l = 10L;
        System.out.println("Long: " + (i == j)); // prints false
        k = 128L;
        l = 128L;
        System.out.println("Long: " + (i == j)); // prints false

    }
}

Ответ 1

Цель постоянного пула - уменьшить накладные расходы памяти, требуемые при сохранении нескольких копий констант. В случае String s JVM по своей сути требуется поддерживать некоторый объект для каждой отдельно различимой константы, а спецификация Java в основном говорит о том, что JVM должен дедуплицировать объекты String при загрузке классов. Способность вручную размещать String в пуле через intern является недорогой и позволяет программистам идентифицировать определенные значения (такие как свойства), которые будут использоваться для жизни программы, и сообщить JVM о том, чтобы вывести их из способ нормального сбора мусора.

Объединение числовых констант, с другой стороны, не имеет большого смысла по нескольким причинам:

  • Большинство конкретных номеров никогда не используются в данном программном коде.
  • Когда числа используются в коде, встраивание их в код в качестве непосредственных значений кода операции является менее дорогостоящим с точки зрения памяти, чем попытка их объединения. Обратите внимание, что даже пустой String несет вокруг char[], int для своей длины, а другой для hashCode. Для числа, напротив, требуется не более восьми мгновенных байтов.
  • Как и в случае с последними версиями Java, объекты Byte, Short и Integer от -128 до 127 (от 0 до 127 для Character) отбираются по соображениям производительности, а не для экономии памяти. Этот диапазон, по-видимому, был выбран потому, что он представляет собой диапазон подписанного байта, и он будет охватывать большое количество общих применений, в то время как было бы нецелесообразно пытаться обеспечить очень большое количество значений.

В качестве примечания, имейте в виду, что правила интернирования были сделаны задолго до введения автобоксинга и общих типов в Java 5, что значительно расширило количество классов-оболочек, которые были случайно использованы. Это увеличение использования привело к тому, что Sun добавило эти общие значения в постоянный пул.

Ответ 2

Ну, потому что объекты String неизменяемы, он безопасен для множественных ссылок на "общий" один и тот же объект String.

public class ImmutableStrings
{
public static void main(String[] args)
{
    String one = "str1";
    String two = "str1";

    System.out.println(one.equals(two));
    System.out.println(one == two);
}
}

// Output

true
true

В таком случае нет необходимости создавать два экземпляра одинакового объекта String. Если объект String можно изменить, так как StringBuffer можно изменить, мы будем вынуждены создавать два отдельных объекта. Но, поскольку мы знаем, что объекты String не могут измениться, мы можем безопасно совместно использовать объект String среди двух ссылок String, один и два. Это делается через пул строк.

Вы можете пройти через эту , чтобы узнать подробности.