Точно. Вы должны использовать StringBuilder, хотя, если безопасность потока не является проблемой.
В качестве примечания: может быть несколько объектов String, использующих один и тот же задний символ [] - например, всякий раз, когда вы используете substring (), новый символ [] не создается, что делает его весьма эффективным.
Кроме того, компиляторы могут выполнить некоторую оптимизацию для вас. Например, если вы делаете
static final String FOO = "foo";
static final String BAR = "bar";
String getFoobar() {
return FOO + BAR; // no string concatenation at runtime
}
Я не удивлюсь, если компилятор будет использовать StringBuilder для оптимизации строковой конкатенации, где это возможно, если не в будущем.