По сути этот вопрос продолжает другой вопрос
Во многих статьях говорится, что при создании строк без new через литерал строка попадает в пул строк. В противном случае необходим метод intern. Как тогда объяснить поведение ниже ?
String s2 = "hello";
String s1 = "hello";
System.out.println(s1 == s2); // true
System.out.println("hel" + "lo" == "hello"); // true
s1 = "hello";
s2 = "hel";
String s3 = "lo";
System.out.println(s1 == s2 + s3); // false
System.out.println(s2 + s3 == "hel" + "lo"); //false
Если в последнем случае s2 ссылается туда же куда и литерал "hel", и с s3 такая же история, то почему "hel" + "lo" не равно (по ссылке) s2 + s3 ?
Ответ
Строка может попасть в пул констант в двух случаях:
На этапе компиляции.
Компилятор проходит по всем строкам в исходном коде и добавляет их в пул констант. Если в коде есть какие-то места, в которых нужны вычисления и компилятор может их произвести, то он делает это. В Вашем примере это System.out.println("hel" + "lo" == "hello");. Сконкатенировал "hel" + "lo" и положил в пул.
Вызов String.intern()
Описание метода (ссылка на документацию).
Здесь надо обязательно указать границы применения данного способа. Данный методы выглядит очень заманчиво: "мы можем сократить использование памяти, и производительность в програме!! Это громадная оптимизация!!"
Из intern пула НЕ возможно удалить данные
intern медленнее чем реализация (через ConcurrentHashMap, например) интернирования. Потому что во внутренней таблице (в которой хранятся интерниованные строки) всего около 60 000 бакетов и большОе количество строк может забить эти бакеты. Покачто эта Map не ресайзится.
intern может влиять на работу всей JVM так как таблица используется для хранения информации о классах
Если мне не верите, то Алексею Шипилеву должны поверить (про intern с 32 минуты).
Комментариев нет:
Отправить комментарий