2016-10-06 13 views
2

Из того, что я понимаю, Объединение строк «+» оператор в Java реализуется с помощью StringBuilder, например, что-то вроде:Что касается «+» оператора и его реализации StringBuilder

String s = "foo" + "bar" 

внутренне компилируется как:

String s = new StringBuilder().append("foo").append("bar").toString(); 

Так что я пытался что-то вроде этого:

String foo1 = "foobar"; 
String foo2 = new String("foobar"); 
String foo3 = "foo" + "bar"; 
char[] fooarray = {'f','o','o','b','a','r'}; 
String foo4 = new String(fooarray); 

Далее я тестировал они друг против друга используют == operator. Результаты были в основном тем, что я ожидал: foo2 и foo4 не возвращали «==» для любой другой String.

Однако foo3 == foo1 возвращает true. Что является причиной этого ? Метод toString класса StringBuilder internall вызывает «новую строку», поэтому не должен быть foo3 уникальным объектом, как foo2?

+11

Объединение строк из двух строки * литералы * сделано в * компилятором *, а не во время выполнения. Поэтому запись '' foo "+" bar "' такая же, как и запись 'foobar''. Он позволяет разделить строковый литерал на несколько строк без ущерба для производительности. – Andreas

+3

Кроме того, если ваши строки являются «final», тогда даже «String s = s1 + s2» произойдет во время компиляции, если 's1' и' s2' являются ссылками на строковые литералы – TheLostMind

ответ

4

Причина, по которой foo3 == foo1 возвращает значение true из-за объединения строк.

При конкатенации строковых литералов (даже final строки, которые не литералы) конкатенация происходит во время компиляции, поэтому, когда программа выполняет значения String foo1 = "foobar"; и String foo3 = "foobar";.

String pool или String table - это специальная область в куче, в которой хранятся ссылки на String.

Теперь, когда вы создаете String foo1, он хранится в пуле, если нет другого строкового литерала со значением foobar. Но в случае foo3 уже есть строковый литерал со значением foobar, поэтому foo1 и foo3 указывает на тот же объект в пуле строк, это делается для сохранения памяти.

При создании строки с новым ключевым словом объект находится в куче, но вне пула строк.

Если вы хотите, чтобы строка, созданная с новым ключевым словом, была в пуле String, если в пуле уже существует такое же значение, вам нужно вызвать метод String intern() и назначить обратную ссылку на переменную String.

Для получения дополнительной информации - What is the Java string pool and how is “s” different from new String(“s”)?