Java pass by reference
В чем разница между этими 2 кодами:
Код А:
Foo myFoo;
myFoo = createfoo();
Где
public Foo createFoo()
{
Foo foo = new Foo();
return foo;
}
Против Кода B:
Foo myFoo;
createFoo(myFoo);
public void createFoo(Foo foo)
{
Foo f = new Foo();
foo = f;
}
Есть ли какие-либо различия между этими двумя частями кодов?4 ответа:
Java всегда передает Аргументы по значению, а не по ссылке.
Позвольте мне объяснить это с помощью пример:
public class Main { public static void main(String[] args) { Foo f = new Foo("f"); changeReference(f); // It won't change the reference! modifyReference(f); // It will modify the object that the reference variable "f" refers to! } public static void changeReference(Foo a) { Foo b = new Foo("b"); a = b; } public static void modifyReference(Foo c) { c.setAttribute("c"); } }
Я объясню это шагами:
Объявляет ссылку с именем
f
типаFoo
и присваивает ее новому объекту типаFoo
с атрибутом"f"
.Foo f = new Foo("f");
Со стороны метода объявляется ссылка типа
Foo
с именемa
, которая первоначально назначаетсяnull
.public static void changeReference(Foo a)
- При вызове метода
changeReference
Ссылкаa
будет присвоена объекту, который передается в качестве аргумента.changeReference(f);
Объявляет ссылку с именем
b
типаFoo
и присваивает ее новому объекту типаFoo
с атрибутом"b"
.Foo b = new Foo("b");
a = b
является повторное присвоение ссылкиa
неf
объекту, чей атрибут является"b"
.
При вызове метода
modifyReference(Foo c)
создается ссылкаc
и присваивается объекту с атрибутом"f"
.
c.setAttribute("c");
изменит атрибут объекта, на который указывает ссылкаc
, и это тот же самый объект, на который указывает Ссылкаf
.Надеюсь, теперь вы понимаете, как передача объектов в качестве аргументов работает в Java:)
Поскольку Java строго "передается по значению" и даже ссылки на объекты передаются по значению, второй код не будет работать должным образом. Смотрите раздел "Связанные" справа для многочисленных обсуждений по этому вопросу.
Думайте о параметрах метода как о своих собственных переменныхобъявлениях . Если бы вы заменили вызов метода одним блоком кода, это выглядело бы так:
Foo myFoo; { //Method call starts here Foo foo; foo = myFoo; Foo f = new Foo(); foo = f; } //Method call ends here
Даже если параметр метода имеет то же имя, что и другая переменная, параметр метода все равно является его собственной, уникальной ссылкой, о которой знает только метод. Это то же самое, что и англ.Фуад говорит выше.
Еще один важный момент, который вы должны знать, - это тип объекта, который вы передаете в метод. будь то изменяемый объект или неизменяемый объект. Если вы передадите неизменяемый объект, такой как String, он создаст другую копию и выполнит модификацию. Изменения не отражаются на вашей оригинальной копии.