При подготовке к экзамену SCJP (или OCPJP, как его теперь называют) меня поймали на несколько фиктивных вопросов, касающихся значения pass-by-(reference) и неизменности.
Насколько я понимаю, когда вы передаете переменную в метод, вы передаете копию битов, которые представляют, как добраться до этой переменной, а не сам фактический объект.
Копия, которую вы отправляете, указывает на тот же объект, поэтому вы можете изменить этот объект, если он является изменяемым, например добавить к StringBuilder. Однако если вы что-то делаете с неизменяемым объектом, например увеличиваете целое число, локальная ссылочная переменная теперь указывает на новый объект, а исходная ссылочная переменная не обращает на это внимания.
Рассмотрим мой пример здесь:
public class PassByValueExperiment
{
public static void main(String[] args)
{
StringBuilder sb = new StringBuilder();
sb.append("hello");
doSomething(sb);
System.out.println(sb);
Integer i = 0;
System.out.println("i before method call : " + i);
doSomethingAgain(i);
System.out.println("i after method call: " + i);
}
private static void doSomethingAgain(Integer localI)
{
// Integer is immutable, so by incrementing it, localI refers to newly created object, not the existing one
localI++;
}
private static void doSomething(StringBuilder localSb)
{
// localSb is a different reference variable, but points to the same object on heap
localSb.append(" world");
}
}
Вопрос. Только ли неизменяемые объекты ведут себя таким образом, а изменяемые объекты могут быть изменены с помощью ссылок, передаваемых по значению? Правильно ли я понимаю или есть другие преимущества в этом поведении?