Я знаю, что это, вероятно, очень глупо, но во многих местах утверждается, что класс Integer в Java неизменен, но следующий код:
Integer a=3;
Integer b=3;
a+=b;
System.out.println(a);
Выполняется без каких-либо проблем, давая (ожидаемый) результат 6. Таким образом, фактически изменилось значение a. Разве это не значит, что Integer изменчив? Вторичный вопрос и небольшой оффтоп: «Неизменяемые классы не нуждаются в конструкторах копирования». Кто-нибудь хочет объяснить, почему?
java
immutability
mutable
К. Стефф
источник
источник
Ответы:
Неизменяемость не означает, что
a
никогда не может равняться другому значению. Например,String
тоже неизменяемо, но я все еще могу это сделать:str
не был изменен,str
теперь это полностью новый экземпляр объекта, как и вашInteger
. Таким образом, значениеa
не мутировать, но он был заменен совершенно новым объектом, то естьnew Integer(6)
.источник
+=
операции.Integer.valueOf(int)
и этот метод поддерживает кешInteger
объектов. Таким образом, результат+=
наInteger
переменной может быть объектом , который существовал ранее (или это может быть даже тот же объект ... в случаеa += 0
).a
является «ссылкой» на какое-то целое число (3), ваше сокращение наa+=b
самом деле означает следующее:Так что нет, целые числа неизменяемы, но указывающие на них переменные - *.
* Возможно наличие неизменяемых переменных, они обозначаются ключевым словом
final
, что означает, что ссылка не может изменяться.источник
Вы можете определить, что объект изменился, используя
System.identityHashCode()
(лучший способ - использовать простой,==
но не так очевидно, что ссылка, а не значение изменилась)отпечатки
Вы можете видеть, что базовый «id» объекта, на который
a
ссылается, изменился.источник
На начальный вопрос:
Целое число неизменяемо, поэтому то, что произошло выше, означает, что «a» изменилось на новую ссылку значения 6. Начальное значение 3 осталось без ссылки в памяти (оно не было изменено), поэтому оно может быть обработано сборщиком мусора.
Если это происходит со строкой, она будет храниться в пуле (в пространстве PermGen) дольше, чем целые числа, поскольку она ожидает иметь ссылки.
источник
Да Целое число неизменяемо.
A - это ссылка, которая указывает на объект. Когда вы запускаете + = 3, это переназначает A для ссылки на новый объект Integer с другим значением.
Вы никогда не изменяли исходный объект, а указывали ссылку на другой объект.
О разнице между объектами и ссылками читайте здесь .
источник
Неизменяемость не означает, что вы не можете изменить значение переменной. Это просто означает, что любое новое присвоение создает новый объект (назначает ему новую ячейку памяти), а затем ему присваивается значение.
Чтобы понять это для себя, выполните целочисленное присваивание в цикле (с целым числом, объявленным вне цикла) и посмотрите на живые объекты в памяти.
Причина, по которой конструктор копирования не нужен для неизменяемых объектов, проста в здравом смысле. Поскольку каждое присвоение создает новый объект, язык технически уже создает копию, поэтому вам не нужно создавать еще одну копию.
источник
Причина в том, что редко возникает необходимость в копировании (или даже в любой точке копирования) экземпляра неизменяемого класса. Копия объекта должна быть «такой же, как» оригинал, и если она такая же, создавать ее не нужно.
Однако есть некоторые основные предположения:
Предполагается, что ваше приложение не придает никакого значения идентификатору объекта экземпляров класса.
Предполагается, что класс перегружен
equals
иhashCode
что копия экземпляра будет «такой же, как» оригинал ... в соответствии с этими методами.Одно из этих предположений или оба могут быть ложными, и это может служить основанием для добавления конструктора копирования.
источник
Вот как я понимаю неизменное
Если бы int мог изменяться, "a" напечатало бы 8, но это не так, потому что оно неизменяемо, поэтому оно равно 3. Ваш пример - это просто новое присвоение.
источник
Я могу прояснить, что Integer (и другие его кредо, такие как Float, Short и т. Д.) Неизменны с помощью простого образца кода:
Результатом будет он Hi There 100 вместо ожидаемого результата (в случае, если оба объекта sb и i являются изменяемыми объектами) Hi There 1000
Это показывает, что объект, созданный i в main, не изменяется, тогда как sb изменяется.
Итак, StringBuilder продемонстрировал изменчивое поведение, но не Integer.
Итак, целое число неизменяемо. Следовательно, доказано
источник
private void doStringBuilder(StringBuilder sb){ sb = new StringBuilder(); }
тоsb
не изменится.private void doInteger(Integer i){ System.out.println( i == 100 ); i=1000; System.out.println( i == 100 ); }
Выход:
Привет-пока 1000 5000 1000 5000 д а
Итак, char является изменяемым, String Integer и int неизменяемы.
источник