Что такое пул строк в Java? [дубликат]



этот вопрос уже есть ответ здесь:



Я запутался в StringPool в Java. Я наткнулся на это, читая строковую главу на Java. Пожалуйста, помогите мне понять, в непрофессиональных терминах, что StringPool фактически делать.

555   4  

4 ответов:

это выводит true (даже если мы не используем equals способ: правильный способ сравнения строк)

    String s = "a" + "bc";
    String t = "ab" + "c";
    System.out.println(s == t);

когда компилятор оптимизирует ваши строковые литералы, он видит, что как s и t имеют одинаковое значение и поэтому вам нужен только один строковый объект. Это безопасно, потому что String является неизменным в Java.
В результате, оба s и t указывать на тот же объект и немного памяти.

название 'string pool' происходит от идеи, что все уже определенные строки хранятся в некотором "пуле" и перед созданием нового String объект компилятор проверяет, если такая строка уже определена.

Я не думаю, что это на самом деле делает много, похоже, что это просто кэш для строковых литералов. Если у вас есть несколько строк, значения которых одинаковы, все они будут указывать на один и тот же строковый литерал в пуле строк.

String s1 = "Arul"; //case 1 
String s2 = "Arul"; //case 2 

в случае 1 литерал s1 создается заново и хранится в пуле. Но в случае 2, литерал s2 ссылается на s1, он не будет создавать новый вместо этого.

if(s1 == s2) System.out.println("equal"); //Prints equal. 

String n1 = new String("Arul"); 
String n2 = new String("Arul"); 
if(n1 == n2) System.out.println("equal"); //No output.  

http://p2p.wrox.com/java-espanol/29312-string-pooling.html

давайте начнем с цитаты из спецификации виртуальной машины:

загрузка класса или интерфейса, который содержит строковый литерал, может создать новый строковый объект (§2.4.8) для представления этого литерала. Это может не произойти, если объект a String уже был создан для представления предыдущего вхождения этого литерала или если строка.метод intern был вызван для строкового объекта, представляющего ту же строку, что и буквальный.

это может не произойти - это намек, что есть что-то особенное String объекты. Обычно вызов конструктора будет всегда создать новый экземпляр класса. Это не относится к строкам, особенно когда строковые объекты "создаются" с помощью литералов. Эти строки хранятся в глобальном хранилище (пуле) - или, по крайней мере, ссылки хранятся в пуле, и всякий раз, когда новый экземпляр уже известных строк при необходимости виртуальная машина возвращает ссылку на объект из пула. В псевдо-коде это может выглядеть так:

1: a := "one" 
   --> if(pool[hash("one")] == null)  // true
           pool[hash("one") --> "one"]
       return pool[hash("one")]

2: b := "one" 
  --> if(pool[hash("one")] == null)   // false, "one" already in pool
        pool[hash("one") --> "one"]
      return pool[hash("one")] 

так что в этом случае переменные a и b содержат ссылки на тот же

когда JVM загружает классы или иным образом видит литеральную строку или некоторый код interns строка, он добавляет строку в основном скрытую таблицу поиска, которая имеет одну копию каждой такой строки. Если добавляется другая копия, среда выполнения организует ее так, чтобы все литералы ссылались на один и тот же строковый объект. Это называется "интернирование". Если вы говорите что-то вроде

String s = "test";
return (s == "test");

это true, потому что первый и второй "тест" на самом деле один и тот же объект. Сравнение интернированных строк таким образом может быть много,много быстрее String.equals, так как есть одно сравнение ссылок, а не куча char сравнения.

вы можете добавить строку в бассейн, вызвав String.intern(), который вернет вам объединенную версию строки (которая может быть той же строкой, которую вы интернируете, но вы были бы сумасшедшими, чтобы полагаться на это-вы часто не можете точно знать, какой код был загружен и запущен до сих пор и интернирован той же строкой). Застаивание версия (строка, возвращенная из intern) будет равно любому идентичному литералу. Например:

String s1 = "test";
String s2 = new String("test");  // "new String" guarantees a different object

System.out.println(s1 == s2);  // should print "false"

s2 = s2.intern();
System.out.println(s1 == s2);  // should print "true"

Comments

    Ничего не найдено.