Возвращает ли Java по ссылке или по значению - PullRequest
16 голосов
/ 04 сентября 2011

У меня есть HashMap:

private HashMap<String, Integer> cardNumberAndCode_ = new HashMap<String, Integer>();

И позже я делаю это:

Integer balance = cardNumberBalance_.get(cardNumber);
System.out.println(balance);
balance = 10;
Integer newBalance = cardNumberBalance_.get(cardNumber);
System.out.println(newBalance);

Сначала печатается 1000, а во второй раз печатается 1000, значение не меняется. Почему Java возвращает целое число по значению, а не по ссылке?

Ответы [ 4 ]

17 голосов
/ 04 сентября 2011

Метод get возвращает копию ссылки на сохраненное целое число ...

Присвоение нового значения переменной, в которой хранится эта копия, указывает на значение 10 будет не изменять ссылку на карте.

Это сработало бы, если бы вы могли сделать balance.setValue(10), но, поскольку Integer является неизменным классом, это не вариант.

Если вы хотите, чтобы изменения вступили в силу на карте, вам придется заключить баланс в (изменяемый) класс:

class Balance {
    int balance;
    ...
}

Balance balance = cardNumberBalance_.get(cardNumber);
System.out.println(balance.getBalance());
balance.setBalance(10);
Balance newBalance = cardNumberBalance_.get(cardNumber);
System.out.println(newBalance.getBalance());

Но вы, вероятно, захотите сделатькак-то так:

cardNumberBalance_.put(cardNumber, 10);
2 голосов
/ 04 сентября 2011

Переменная Integer содержит ссылку на объект.Объект Integer является неизменным, и вы не можете его изменить.Когда вы выполняете

balance = 10; // replace the previous Integer reference with a different one.

Обычный способ сделать это - использовать

cardNumberBalance_.put(cardNumber, 10);

Альтернативой, которая не используется так часто, является использование AtomicInteger или использование собственного MutableInteger

private final Map<String, AtomicInteger> cardNumberAndCode_ = new HashMap<String, AtomicInteger>();

AtomicInteger balance = cardNumberBalance_.get(cardNumber);
balance.set(10);
1 голос
/ 04 сентября 2011

Результат присваивания

balance = 10;

означает, что новый экземпляр Integer создается со значением 10, и его ссылка присваивается переменной balance. Он не меняет объект, который вы получаете с карты, то есть объект, сохраненный на карте, остается неизменным.

Если вам нужно изменить значение баланса, вы должны заключить его в изменяемый класс, как aioobe описывает .

1 голос
/ 04 сентября 2011

Java не поддерживает передачу по ссылке (и возврат по ссылке). См. Является ли Java "передачей по ссылке" или "передачей по значению"?

...