【问题标题】:Java pass by referenceJava 通过引用传递
【发布时间】: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。

标签: java parameter-passing terminology pass-by-reference pass-by-value


【解决方案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");
     }
}

我将分步解释:

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

    Foo f = new Foo("f");
    

  2. 在方法方面,声明了一个名为 a 的类型为 Foo 的引用,并且它最初分配给 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 NOT f 重新分配给其属性为 "b" 的对象。


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

  7. 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),它将创建另一个副本并进行修改。更改不会反映在您的原始副本中。

      【讨论】:

      • 不,语言中没有“可变”或“不可变”的概念。因此,它们的传递方式没有区别。 “更改不会反映在您的原始副本中。”根据定义,不可变对象是没有方法可以“改变”的对象,因此这种说法没有意义。
      猜你喜欢
      • 2011-05-02
      • 1970-01-01
      • 2011-04-21
      • 2015-08-09
      • 2016-02-02
      • 2017-09-25
      • 2011-01-31
      • 1970-01-01
      相关资源
      最近更新 更多