Как сказал bzabhi, строки являются неизменяемыми в Java. Это означает, что строковый объект никогда не изменится. Это не означает, что вы не можете изменить строковые переменные, просто вы не можете изменить базовое представление строки в памяти. для примера:
String str = "Hello";
str += " World!";
После выполнения этих строк str будет указывать на новую строку в памяти. Исходная строка «Hello» все еще существует в памяти, но, скорее всего, она не будет там долго. Если предположить, что нет никаких смягчающих обстоятельств, ничто не будет указывать на исходную строку, поэтому она будет собирать мусор.
Полагаю, что лучший способ выразить это - сказать, что при выполнении строки 2 примера создается новая строка в памяти из конкатенации исходной строки и строки, добавляемой к ней. Переменная str, которая является просто ссылкой на ячейку памяти, затем изменяется, чтобы указывать на только что созданную переменную.
Я не особо осведомлен в этом вопросе, но, насколько я понимаю, это то, что происходит со всеми "не примитивными" ценностями. Все, что в какой-то момент происходит от Объекта, следует этим правилам. Примитивные значения, такие как int, bools, chars, float и double, позволяют изменять действительное значение в памяти. Итак, из этого:
int num = 5;
num += 2;
фактическое значение в памяти изменяется. Вместо создания нового объекта и изменения ссылки этот пример кода просто изменит значение в памяти для переменной num.
Что касается того, почему это так, то это просто дизайнерское решение создателей Java. Я уверен, что кто-то прокомментирует, почему это было сделано, но это не то, что я знаю.