4

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.

Andrew Brēza
  • 7,705
  • 3
  • 34
  • 40
RandomUser
  • 4,140
  • 17
  • 58
  • 94

10 Answers10

10

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

Lincoded
  • 425
  • 2
  • 13
6

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.

MByD
  • 135,866
  • 28
  • 264
  • 277
  • It doesn't help that _shadowing_ is in play here... You may want to tweak your explanations/example, as it isn't necessarily immediately obvious what you're pointing out. – Clockwork-Muse Oct 31 '11 at 15:44
3

Java is passing always parameters by values. In your case the object reference is passed by value. See this article that explain how and why.

http://javadude.com/articles/passbyvalue.htm

Massimo Zerbini
  • 3,125
  • 22
  • 22
1

I've heard Java's memory model described as passing "value by reference." Any "primitive" types (int, e.g.) are passed by value. Anything that extends Object is also passed by value... but the value of an object is a reference to its location in the heap.

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
1

Java is pass by value. The thing is just, that what you called an object is in reality a reference to an object. The value of which was passed..

nfechner
  • 17,295
  • 7
  • 45
  • 64
1

Everything is passed by value but an object itself is NEVER passed. Just its reference is passed, by value.

Think about objects as stored in a sort of warehouse, for every object you have an identifier that states where the object is. Ok, now wherever you pass an object from a method to another you just pass the identifier.

Jack
  • 131,802
  • 30
  • 241
  • 343
1

What is passed by value is the reference to the list, not the list itself. If you know little C++, than it's similar to copying the pointer of the list. The 2 objects have 2 different references that reference the SAME list. That's the explanation for this output.

duduamar
  • 3,816
  • 7
  • 35
  • 54
1

In the following varInt holds the value "2"

int varInt = 2; 

And varObj in the following holds the value "which happens to be the reference" to the new object:

Object varObj = new Object(); 

So, if you call methods as follows -

someVar.method1(varInt); // the value 2 is passed here

someVar.method2(varObj); // the value which is the reference is passed here

So Java is always Pass-By-Value.

Marcin Gil
  • 68,043
  • 8
  • 59
  • 60
Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
0

Java is not pass by value. Only primitives are passed by value, objects are passed by reference. Since you use the same list for both friend lists, the friends are the same as well.

Steven
  • 2,437
  • 5
  • 32
  • 36
  • 1
    Objects are passed by Reference, References to objects are passed by Value. Get your terminology straight. In essence what you pass is always the reference, but everyone thinks from the point of view of the object. – Steven Oct 31 '11 at 14:26
  • 1
    `"References to objects are passed by Value"` this is correct. Real pass-by-reference like in C and C++ is not possible in Java. This is shown in MByD's answer. Get *your* terminology straight. – NullUserException Oct 31 '11 at 14:34
  • @NullUserExceptionఠ_ఠ sorry, but this is just nonsense. In C you can pass an int by reference. You obviously can't do that in Java. However as objects are allways referenced by reference they are obviously passt by reference. And yes for the nitpickers, the actual reference is passed by value, just as in C ... I would suggest instead of brain masturbating and showing how super smart you are, that you lower yourself to the level of the asker. So he has a chance to understand what you say ... everything else is jsut a waste of your and his time. – Angel O'Sphere Oct 31 '11 at 14:46
  • @AngelO'Sphere It's not "brain masturbating" - the notion that objects are passed by reference in Java is fundamentally incorrect. The reason the OP is asking this question is because they don't understand how parameter passing works in Java. Telling them the wrong thing is doing them a great disservice. From [Oracle](http://download.oracle.com/javase/tutorial/java/javaOO/arguments.html) itself: "Reference data type parameters, such as objects, are also passed into methods *by value*". **There is no such thing as pass by reference in Java.** – NullUserException Oct 31 '11 at 14:59
  • And again, MByD's answer illustrates perfectly why objects are **not** passed by reference. – NullUserException Oct 31 '11 at 15:00
  • @NullUserExceptionఠ_ఠ you No it is not fundamentally incorrect. If it was _fundamentally_ incorrect then objects itself could be passed as value. Obviously you fail to understand how difficult it is to understand for a novice that a reference can be passed as value, but object behind the reference not, and the object is in your eyes still not passed as reference. Frankly: for a novice this simply makes no sense at all. So, challange, lets see if you get it right: can you pass an object in Java by value? Yes or no? – Angel O'Sphere Oct 31 '11 at 15:07
  • 1
    @AngelO'Sphere Java always passes *references* by value, not the objects themselves. The answer to your question is no, if by "pass an object by value" you mean passing a copy of the object. I fail to see how this is hard for a novice to understand. Rather than teaching them a simplification that is plain *wrong*, why not teach them the *right* thing? Or else, they'll start asking why `public void nullify(Object myObj) { myObj = null; }` doesn't work like it should if Java actually supported pass-by-reference. – NullUserException Oct 31 '11 at 17:58
  • @NullUserExceptionఠ_ఠ "I fail to see how this is hard for a novice to understand." Then stop giving advice to novices. Sorry, it makes me sad how stupid someone is who obviously is as bright as you. You don't understand the difference between semantics and implementation. You don't understand how to teach a novice. Nevertheless you post endless comments ... where obviously no one except you and me even can get what it is about. Why not teaching them the right thing? Because your "right" is wrong. Semantically java Objects are passed by reference. No one cares if the reference is an "address" – Angel O'Sphere Nov 01 '11 at 20:35
  • @AngelO'Sphere I give up arguing with you. [Everyone in this site](http://stackoverflow.com/questions/40480/is-java-pass-by-reference) with minimal Java knowledge agrees that there is no pass by reference in Java. And if you want to insult my communication skills, that's fine. I have 30 times as much as reputation as you answering only 6 times as many questions than you did, so I think my communication skills are fine. – NullUserException Nov 01 '11 at 21:00
0

Only primitives in Java are passed by value, objects and arrays are by reference.

socha23
  • 10,171
  • 2
  • 28
  • 25