Java: передача параметров по ссылке и значению
В java примитивные типы должны передаваться в функцию по значению, все ссылочные - как ссылки (по сути ссылка передается по значению, но она все еще является ссылкой, поэтому должен достигаться эффект передачи по ссылке). Почему тогда следующий код напечатает 0, если я передаю в функцию не примитивный тип int, а ссылочный Integer?
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
Integer a = new Integer(0);
hmm(a);
System.out.println(a);
}
public static void hmm(Integer a)
{
a += 5;
}
}
Ответы (3 шт):
Операция инкремента у экземпляра Integer приводит к созданию нового объекта, а поскольку в метод передаётся копия ссылки, то при инкременте она перестаёт ссылаться на старый объект в куче и начинает ссылаться на новый. Оригинальная ссылка в методе main будет ссылаться на старый объект до изменения.
Класс Integer является immutable, то есть неизменяемым.
По сути код:
a+=5;
эквивалентен:
Integer a = new Integer(a.intValue()+5);
То есть создается новый экземпляр Integer
Да, действительно, при передаче классов-обёрток вроде Integer, Boolean, Byte и так далее в методы изменения не отражаются на внешних объектах. Всё дело в том, что эти классы являются неизменяемыми. То есть значение, записанное в Integer, изменить нельзя. Когда вы пытаетесь провести операцию, изменяющую значение этой переменной, по факту создаётся новый объект с новым значением.
Подробнее об этом можно прочесть здесь. Также там описано, почему в Java всё передаётся по значению: и примитивные типы, и объекты. И как не запутаться в этих понятиях