不变和传递价值

时间:2011-11-24 12:53:35

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

我有以下代码,其中有 一个可变的Person类,String和一个修改String和Person实例的方法

    class Person{

int a = 8;

public int getA() {
    return a;
}

public void setA(int a) {
    this.a = a;
}

@Override
public String toString() {
    return "Person [a=" + a + "]";
}

  }

-

public class TestMutable {
public static void main(String[] args)
{
    Person p = new Person();
    p.setA(34);


    String s = "bar";

             modifyObject(s, p);   //Call to modify objects

    System.out.println(s);
    System.out.println(p);

}



private static void modifyObject(String str, Person p)
{

        str = "foo";
        p.setA(45);

}

  }

输出符合预期。它打印

           bar
          Person [a=45]

现在,我的问题是

你说str =“foo”的地方发生了什么?

最初我们假设s ='bar'且数据位于0x100内存

现在将字符串的引用传递给另一个方法,另一个方法尝试使用s =“foo”将内存位置(0x100)的内容更改为“foo”。这是发生了什么,或者'foo'是在不同的内存位置创建的?

java是否按值传递引用?

4 个答案:

答案 0 :(得分:27)

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 change 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的{​​{1}}类型的引用,并将其分配给类型为Foo的新对象,其属性为Foo

"f"

enter image description here

2-从方法方面,声明了名为Foo f = new Foo("f"); 的{​​{1}}类型的引用,并且它最初分配给Foo

a

enter image description here

3-当你调用方法null时,引用public static void changeReference(Foo a) 将被分配给作为参数传递的对象。

changeReference

enter image description here

4-声明名为a的{​​{1}}类型的引用,并将其分配给类型为changeReference(f); 的新对象,其属性为b

Foo

enter image description here

5- Foo正在将引用"b" NOT Foo b = new Foo("b"); 重新分配给其属性为a = b的对象。

enter image description here


6-当您调用a方法时,会创建一个引用f,并将其分配给具有属性"b"的对象。

enter image description here

7- modifyReference(Foo c)会更改引用c的对象的属性指向它,并且它是引用"f"指向它的同一对象。

enter image description here

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

答案 1 :(得分:2)

modifyObject中,当您分配到str时,您不会改变str,而是设置它以使其指向不同的对象。由于它是按值传递的,因此str方法本地的modifyObject指针是smain指针的副本,因此当您更改前者时,它不会稍后影响乐。

另一方面,当谈到p时,modifyObject中的那个仍然是main中的一个副本,但两个指针都指的是同一个对象。内存,因此如果你从modifyObject调用一个方法,你实际上是在改变p指向的东西。

答案 2 :(得分:2)

有时人们在通过引用传递时会感到困惑。可以更改引用引用的对象(给出引用传递的印象),但是不可能修改引用本身。所以它仍然是值得传递的。

答案 3 :(得分:1)

在这个函数中调用“modifyObject(s,p);”您正在将变量s的值发送到modifyObject方法的局部变量str。因此,创建了一个新变量,其值已更改,但原始变量保持不变。