Ответ 1
i
является ссылкой. Ваш код меняет ссылку i
на другую, равно неизменяемую, Integer
.
final Integer i = Integer.valueOf(5);
может быть более полезным.
Классы Java Wrapper должны быть неизменными. Это означает, что после создания объекта, например,
Integer i = new Integer(5);
его значение не может быть изменено. Однако, делая
i = 6;
отлично.
Итак, что означает неизменность в этом контексте? Это связано с автоматическим боксированием/распаковкой? Если да, есть ли способ предотвратить компилятор от этого?
Спасибо
i
является ссылкой. Ваш код меняет ссылку i
на другую, равно неизменяемую, Integer
.
final Integer i = Integer.valueOf(5);
может быть более полезным.
Неизменяемый означает, что состояние объекта не может быть изменено. В вашем случае вы не изменили объект new Integer(5)
, но вы изменили ссылку i
на другой объект. Надеюсь, это ясно:)
Компилятор использует autoboxes примитивные значения, это означает, что
Integer value = 6;
будет скомпилирован как
Integer value = Integer.valueOf(6);
Integer.valueOf вернет экземпляр Integer с заданным значением. В вашем случае i
теперь будет ссылаться на Integer (6) вместо Integer (5), сам объект Integer (5) не изменится.
Чтобы увидеть это, вы можете сделать следующее
Integer i = new Integer(5);//assign new integer to i
Integer b = i;//b refences same integer as i
i = 6;//modify i
System.out.println(i +"!="+b);
Это будет печатать 6!=5
, если экземпляр integer был изменен, он будет печатать 6!=6
вместо этого.
Чтобы прояснить это, нужно только показать, как назначение Integer только модифицирует ссылку и не изменяет сам экземпляр Integer. Как указывает пользователь @KNU, он не доказывает или не демонстрирует неизменность Integer, насколько я могу сказать, что неизменяемость косвенно объясняется отсутствием методов модификации в его API и требованием, чтобы экземпляры, возвращаемые Integer.valueOf, кэшироваться для определенного диапазона.
Причина i = 6
заключается в том, что автоматическое боксирование перехватывает и превращает его в i = new Integer(6)
. Таким образом, как сказал @Peter, вы теперь указываете на новый объект.
Все классы-обёртки в java являются неизменяемыми. Мы не можем изменить значение объекта класса-обертки после его создания, то есть не можем изменить значение, заключенное в объект. Поскольку классы-обертки используются в качестве объектной формы примитивных типов данных и, если они изменчивы, несоответствия данных будут возникать во время выполнения. Однако вы можете изменить ссылочную переменную класса-оболочки для хранения другого объекта.