Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to explain shallow-copy in Java versus pass by value?

Tags:

java

From what I understand with Java, everything is pass by value. However, when you begin talking about objects which contain other objects things get a bit interesting and i'd like to be able to communicate this better and make sure I fully understand as well. So my take here is that only the primitives within the object are actually copied, on the other hand any objects it contains...the values of those objects are not copied, rather only are copies of those references.

So if we had some object with these members

public class SomeObject {
   private String name;
   private String address;
   private  List<String> friends;

   public SomeObject(String name, String address, List<String> friends) {
      this.name = name;
      this.address = address;
      this.friends = friends;
   }
}

And we did this:

List<String> friendsList = new ArrayList<String>();
        friendsList.add("bob");
        friendsList.add("joe");

        SomeObject so1 = new SomeObject("mike", "123 street", friendsList);

        friendsList.add("zoe");
        friendsList.add("rick");
        SomeObject so2 = new SomeObject("david", "300 ave", friendsList);

        System.out.println(so1.getName() + " " + so1.getAddress());
        for (String friend : so1.getFriends()) {
            System.out.println(friend);
        }

        System.out.println(so2.getName() + " " + so2.getAddress());
        for (String friend : so2.getFriends()) {
            System.out.println(friend);
        }

Our output is this:

mike 123 street
bob
joe
zoe
rick
david 300 ave
bob
joe
zoe
rick

Even though we have created 2 separate objects, they both maintain a reference to the original friendslist. This is why I get a bit tripped up when people say Java is always pass by value.

like image 495
RandomUser Avatar asked Nov 28 '22 10:11

RandomUser


2 Answers

The reference to the list is passed by value, not the list itself, meaning, you cannot change friendsList from within the constructor of SomeObject, but you may change the content it points to.

For example, if the constructor was like this:

public SomeObject(String name, String address, List<String> friends) {
    this.name = name;
    this.address = address;
    this.friends = friends;
    friends = new ArrayList<String>();
}

You will still get the same output although you assigned new list to friends.

like image 35
MByD Avatar answered Dec 05 '22 17:12

MByD


The reference is passed by value, so the pointer to the list is copied, not the list itself.

like image 144
Lincoded Avatar answered Dec 05 '22 16:12

Lincoded