Immutable and pass by value

2019-02-04 23:10发布

I have the following code which has
a mutable Person class, String and a method to modify the instances of String and 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);

}

  }

The output is as expected. It prints

           bar
          Person [a=45]

Now, my question is

What is happening at the place you say str="foo" ?

Initially let's assume that s='bar' and the data resides in 0x100 memory

Now the reference of string is passed to another method, the other method tries to change the contents of the memory location(0x100) to 'foo' using s="foo". Is this what is happening, or is 'foo' is created in differennt memory location ?

Does java pass references by value ?

4条回答
ら.Afraid
2楼-- · 2019-02-04 23:36

In this function call "modifyObject(s, p);" you are sending the value of variable s to modifyObject method's local variable str. So a new variable is created and its value is changed but the original one remains unchanged.

查看更多
萌系小妹纸
3楼-- · 2019-02-04 23:54

Java always passes arguments by value NOT by reference.


Let me explain this through an 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");
     }
}

I will explain this in steps:

1- Declaring a reference named f of type Foo and assign it to a new object of type Foo with an attribute "f".

Foo f = new Foo("f");

enter image description here

2- From the method side, a reference of type Foo with a name a is declared and it's initially assigned to null.

public static void changeReference(Foo a)

enter image description here

3- As you call the method changeReference, the reference a will be assigned to the object which is passed as an argument.

changeReference(f);

enter image description here

4- Declaring a reference named b of type Foo and assign it to a new object of type Foo with an attribute "b".

Foo b = new Foo("b");

enter image description here

5- a = b is re-assigning the reference a NOT f to the object whose its attribute is "b".

enter image description here


6- As you call modifyReference(Foo c) method, a reference c is created and assigned to the object with attribute "f".

enter image description here

7- c.setAttribute("c"); will change the attribute of the object that reference c points to it, and it's same object that reference f points to it.

enter image description here

I hope you understand now how passing objects as arguments works in Java :)

查看更多
狗以群分
4楼-- · 2019-02-04 23:59

In modifyObject, When you assign to str, you're not mutating str, you're setting it so that it points to a different object. Since it's passed by value, the str pointer local to your modifyObject method is a copy of the s pointer in main, so when you change the former, it does not affect le later.

On the other hand, when it comes to p, the one in modifyObject is still a copy of the one in main, but both pointers refer to the very same object in memory, hence if you call a method on it from modifyObject, you're actually mutating the thing pointed to by p.

查看更多
forever°为你锁心
5楼-- · 2019-02-05 00:02

Sometimes people get confused when passing by reference. It's possible to change the object that the reference refers to (giving the impression of pass-by-reference), but it is not possible to modify reference itself. So it still remains pass-by-value.

查看更多
登录 后发表回答