Понятие неизменяемости может быть легко объяснено на этом примере
String s1 = "Hello";
String s2 = "Hi";
String s3 = "Hello";
if (s1 == s2){ System.out.println("s1==s2");}
if (s1 == s3){ System.out.println("s1==s3");}
s1 = "Hi";
if (s1 == s2){ System.out.println("s1==s2");}
if (s1 == s3){ System.out.println("s1==s3");}
Если вы выполните этот фрагмент кода, вы получите
s1==s3
и s1==s2
. Что объясняет этот пример?
Когда вы создали s1, компилятор создал строку «Hello» в своей таблице строк (я не помню его точное имя). Когда вы создали s2, он создает новый объект «Привет». Теперь, когда вы создали s3, компилятор знает, что в его таблице строк уже есть объект «Hello», так почему бы просто не обратиться к s3. Так что s1 = s3 (тиски памяти). То же самое произошло, когда вы присвоили значение «hi» s1, компилятор мог видеть, что «hi» уже находится в памяти, на которую указывает s3, поэтому он также указал на s1.
В случае StringBuffer, Compiler выделяет память для объекта, которым вы можете манипулировать, скорее, «пулом», как в случае String.