2015-04-15 5 views
2

В C++, лучший канонический способ создать многострочные строки из которых я знаю, чтобы создать соседние строки и пусть компилятор сцепить их во время компиляции, например:конкатенация строковых констант в Java

string s = "This is a very long string ...\n" 
    " and it keeps on going..."; 

в Java, единственный способ, которым я знаю, чтобы сделать это с помощью конкатенации:

String s = "This is a very long string ...\n" + 
    " and it keeps on going..."; 

вопрос, означает ли это генерировать одну строку во время выполнения, или же Java фактически конкатенацию во время компиляции также? Причина, по которой возникает вопрос из-за следующее поведение:

String s1 = "abc"; 
String s2 = "abc"; 
System.out.println(s1 == s2); // this prints true, because the compiler 
// generates only one "abc" object 
String s3 = "a"; 
s3 += "bc"; 
System.out.println(s1 == s3); // false 
+1

Да это, попробуйте установить 'String's как константы, используя' статические модификаторы final' и 's1 == s3' будет истинным. Редактировать: О, вам даже не нужно это делать. – Bubletan

+0

ouch! Я отредактирую! Хорошо. В отдельных инструкциях компилятор не оптимизирует, так как я могу продемонстрировать студентам, что s1! = S3. Но в одном заявлении он оптимизирован. – Dov

+1

О, да ладно. 's1 == s3' является' истинным'! –

ответ

2
String s3 = "a"; 
s3 += "bc"; 

такое же, как:

String s3 = "a"; 
s3 = new StringBuilder().append(s3).append("bc").toString(); 

Так он создает новый экземпляр String.

Вы даже можете попробовать:

String s = null; 
s += null; 
System.out.println(s); // prints "nullnull" 
0

Java создает единый неизменный объект за строку, но будет повторно использовать литералы для увеличения производительности.

Эта строка создает неизменяемую строку s1

String s1 = "abc"; 

будет ссылаться на ту же строку, как буквальное s1, так как это является буквальным и может быть оптимизирована компилятором.

String s2 = "abc"; 

Это сравнение идентичности, которое вы задаете, - это S1 и S2 один и тот же объект, а не одна и та же строка. Поскольку компилятор оптимизирован, сделав два объекта ссылкой на ту же неизменяемую строку, это возвращает true.

System.out.println(s1 == s2); 

Это создает 2 неизменяемые строки, затем во время выполнения создается третья строка. Поскольку runtimecant гарантия того, что он может найти уже существующую строку для ссылки efficently он просто создает новый объект и создать новую неизменяемую строку s3

String s3 = "a"; 
s3 = s3 + "bc"; 

Это неверно, так как они являются двумя отдельными объектами данных.

System.out.println(s1 == s3); 

Замечание Строковое равенство возвращает true, вот как мы сравниваем содержимое строкового объекта, а не местоположение объекта. Это первая проверка для проверки личности, вторая - проверка равенства.

System.out.println(s1.equals(s3)); 

Java знает, что создание объекта Data для каждого этапа процесса конкатенации строк очень неэффективно. Чтобы помочь с java hava, введите StringBuilder api, который сделает больше прикладов.

String s = "a"; 
s += "b"; 
s += "c"; 
s += "d"; 
s += "e"; 

приводит строковых объектов '9' создается и записывается в память ...

("a", "b", "ab", "c", "abc", "d", "abcd", "e", "abcde") 

Строка строитель помогает

StringBuilder sb = new StringBuilder(); 
sb.append("a"); 
sb.append("b"); 
sb.append("c"); 
sb.append("d"); 
sb.append("e"); 

Это больше effcient, как он выполняет одну единственную CONCAT и приводит к лучшему использованию памяти.

("a", "b", "c", "d", "e", "abcde") 
+0

Незначительный nit: 's1 == s2' не является объектом сравнения, это сравнение _reference_ объекта. Он проверяет равенство ссылки, указывающей на объект, а не на сам объект. –

+0

Если вы действительно запустили код, который вы опубликовали, вы увидите, что ваша предпосылка неверна. В вашем случае 's1' ** равно ** равно' s3'. – JonK

+0

Вам не хватает точки, s3 равно s1, потому что она находится в литеральном пуле. – Dov

Смежные вопросы