Java передать по ссылке

В чем разница между этими 2 кодами:

Код А:

Foo myFoo;
myFoo = createfoo();

где

public Foo createFoo()
{
   Foo foo = new Foo();
   return foo;
}

Против Код Б:

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");
     }
}

Я объясню это по шагам:

  1. Объявление ссылки с именем f типа Foo и назначить его новому объекту типа Foo с атрибутом "f",

    Foo f = new Foo("f");
    

  2. Со стороны метода, ссылка типа Foo с именем a объявлен и изначально назначен null,

    public static void changeReference(Foo a)
    

  3. Как вы называете метод changeReference, ссылка a будет назначен объекту, который передается в качестве аргумента.

    changeReference(f);
    

  4. Объявление ссылки с именем b типа Foo и назначить его новому объекту типа Foo с атрибутом "b",

    Foo b = new Foo("b");
    

  5. a = b переназначает ссылку a НЕ f к объекту, чей атрибут "b",


  6. Как вы называете modifyReference(Foo c) метод, ссылка c создается и присваивается объекту с атрибутом "f",

  7. 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

Даже если параметр метода имеет то же имя, что и другая переменная, параметр метода остается его собственной уникальной ссылкой, о которой знает только метод. Это то же самое, что говорит Eng.Fouad выше.

Другой важный момент, о котором вам следует знать, - это тип объекта, который вы передаете в метод. будь то изменчивый объект или неизменный объект. Если вы передадите неизменный объект, такой как String, он создаст другую копию и выполнит модификацию. Изменения не отражаются в вашей оригинальной копии.

Другие вопросы по тегам