Java 通过引用传递

Posted

技术标签:

【中文标题】Java 通过引用传递【英文标题】:Java pass by reference 【发布时间】:2012-03-13 08:39:55 【问题描述】:

这两个代码有什么区别:

代码 A:

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;

这两段代码有区别吗?

【问题讨论】:

那里没有“通过引用”。它是按值传递的,值是一个引用。代码 B 无法编译,如果可以,它也不会改变 myFoo。 【参考方案1】:

Java 总是按值而不是按引用传递参数。


让我通过example 解释一下:

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

    在方法方面,声明了一个名为 a 的类型为 Foo 的引用,并且它最初分配给 null

    public static void changeReference(Foo a)
    

    当您调用方法changeReference 时,引用a 将分配给作为参数传递的对象。

    changeReference(f);
    

    声明一个名为b 类型为Foo 的引用,并将其分配给一个类型为Foo 的新对象,其属性为"b"

    Foo b = new Foo("b");
    

    a = b 正在将引用 a NOT f 重新分配给其属性为 "b" 的对象。


    当您调用modifyReference(Foo c) 方法时,会创建一个引用c 并将其分配给具有"f" 属性的对象。

    c.setAttribute("c");会改变引用c指向它的对象的属性,和引用f指向它的对象是同一个对象。

我希望您现在了解在 Java 中如何将对象作为参数传递:)

【讨论】:

您能对比一下“通过引用传递”的样子吗?对我来说有意义的是“按值传递”,它传递 f 引用的对象的内存地址。在 changeReference 中,a 是一个新变量,它引用同一个内存地址,只改变 a 的值(或引用的内存地址)更改 a 指向的内容,而不是 f。如果它是“通过引用传递”,f 将被传入,所以 a = f,改变 a 的值(或引用的内存地址)会改变 f【参考方案2】:

由于 Java 严格“按值传递”,甚至对对象的引用也是按值传递的,因此第二个代码将无法按预期工作。请参阅右侧的“相关”部分,了解关于此的众多讨论。

【讨论】:

【参考方案3】:

将方法参数视为它们自己的变量声明。如果你用一个代码块代替方法调用,它看起来像这样:

Foo myFoo;
                      //Method call starts here
    Foo foo;
    foo = myFoo;
    Foo f = new Foo();
    foo = f;
                      //Method call ends here

即使方法参数与另一个变量同名,方法参数仍然是它自己的,只有方法知道的唯一引用。这与 Eng.Fouad 上面所说的相同。

【讨论】:

【参考方案4】:

您应该知道的另一个重要点是您传递给方法的对象类型。无论是可变对象还是不可变对象。如果您传递一个不可变对象(例如 String),它将创建另一个副本并进行修改。更改不会反映在您的原始副本中。

【讨论】:

不,语言中没有“可变”或“不可变”的概念。因此,它们的传递方式没有区别。 “更改不会反映在您的原始副本中。”根据定义,不可变对象是没有方法可以“改变”的对象,因此这种说法没有意义。

以上是关于Java 通过引用传递的主要内容,如果未能解决你的问题,请参考以下文章

Java 通过引用传递

java引用传递,值传递

Java中对象对象引用堆栈值传递以及引用传递的详解

Java中对象对象引用堆栈值传递以及引用传递的详细解释

Java 递归 - 引用传递的替代方案:

通过 Java 中的套接字传递对包含在“数据包”对象中的对象的引用