2

Consider following case.

    List<Integer> listOne = new ArrayList<>();
    List<Integer> listTwo = new ArrayList<>();
    listOne.add(1);I think this happens due to 
    listOne.add(2);
    listOne.add(3);
    Collections.reverse(listOne);
    listTwo = listOne;  //listTwo has same reference 
    Collections.reverse(listOne);
    System.out.println(listOne);  //out put [1, 2, 3] 
    System.out.println(listTwo);  // same out put

Java is pass by value, where values (for non primitive types) happen to be references. I think this provide survival for java for this kind of scenario. To be honest why java try to avoid pass by reference and try to be different from some of other languages? while java still suffering from pass by reference behaviors?

Edit: additionally please some one explain what happen in above code

Ruchira Gayan Ranaweera
  • 34,993
  • 17
  • 75
  • 115
  • Java is not suffering from pass by reference behaviors? – Juned Ahsan Aug 15 '13 at 09:09
  • Hmm, what are you asking? Java does not try to do anything. It is a language, designed / defined in one way. However I either do not get the question, or it is way to broad to be answered in a meaningful way here. – Matthias Aug 15 '13 at 09:14
  • [Related](http://stackoverflow.com/questions/40480/is-java-pass-by-reference). – Bernhard Barker Aug 15 '13 at 09:15
  • @Dukeling I am asking additional thing and I already red this – Ruchira Gayan Ranaweera Aug 15 '13 at 09:15
  • @Matthias I am sure you can understand what I am asking here. `Java` is my favorite language and I love it. I just ask this to clarify my issue – Ruchira Gayan Ranaweera Aug 15 '13 at 09:17
  • 1
    @Ruchira You should change the title of your question then. – Bernhard Barker Aug 15 '13 at 09:18
  • @Dukeling please edit it appropriately I like to see good discussion here. – Ruchira Gayan Ranaweera Aug 15 '13 at 09:19
  • @Ruchira But in your example you are not passing anything by value or reference. You are just reassigning a variable to a different object. Would you really expect / want something different happening in your code after the line listTwo = listOne. I think there is not many languages who would create a deep copy of an Object for the assignment operator. – Matthias Aug 15 '13 at 09:20
  • @Matthias my point is listOne and listTwo are object. right? then ` listTwo = listOne;` in here java does pass by value. listTwo shoul equal to [3,2,1] and not change back by if i change listOne again. If java does pass by reference result is possible. – Ruchira Gayan Ranaweera Aug 15 '13 at 09:23
  • @Ruchira pass by reference or value only happens when you call a method. So if it would be true pass by value, then calling a method like ´Collections.reverse´ could not change the passed object. If it would be pass by reference you could reassign the variable inside the method and thus produce a lot of side effects. Passing the reference to the object by value is actually a really clever way in the middle. I however do not know anyone who expects to be a variable assignment done by your definition of "pass by value". – Matthias Aug 15 '13 at 09:48
  • 2
    Java is pass by value, and has always been. What is confusing is that `List` here is a *reference* not an object and when you pass the reference by value, that reference is copied, but not the objects. – Peter Lawrey Aug 15 '13 at 10:00
  • @Matthias FYI - There is at least one language I know of that does "true" pass-by-value and copy on assignment - C. In C++ it's similar, except that you can specify your own behaviour for the operators. – Bernhard Barker Aug 15 '13 at 10:54
  • If I understand your question, your asking (1) Why Java language designers chose to make Java pass-by-reference, which is almost certainly "primarily opinion-based" and (2) Explain the code. And the comments you wrote on the answers indicates that you indeed did not read / understand [this](http://stackoverflow.com/questions/40480/is-java-pass-by-reference), because that's exactly what you're asking there. – Bernhard Barker Aug 15 '13 at 11:53
  • @Ruchira If Java would be pass-by-reference you would be able to change reference passed to method, but you are not because Java copies VALUE of reference and passes it to methods local variable - its argument - and re-assigning that variable wont affect original reference. – Pshemo Sep 11 '13 at 10:24
  • @Ruchira ... in your example two list references use same list (object) so it doesn't matter which reference will you pass to `Collections.reverse` method, the result will still be the same, because method will change same object so both references will see those changes. – Pshemo Sep 11 '13 at 10:30

4 Answers4

3

Java does not suffer from pass by reference behaviors, it enjois them :)

when you write

List listOne = new ArrayList<>();

you have three things to consider:

1) a variable, which is a chunk of memory, and is named listOne

2) an object on the heap, with is an instance of ArrayList, which is a larger chunk of memory, and has no name

3) value of the listOne variable, which is not a memory chunk, but is a set of 0s and 1s placed in the memory of the variable listOne, and that value also has no name.

Now when we talk if listOne is passed by value or by reference, we use imprecise jargon which leads to misunderstanding. listOne (thing 1) is not passed at all, neither by value nor by reference. The value of listOne (thing 3) is passed, and this gives access to the ArrayList object (thing 2). So if we use name "listOne" but mean thing 3, it is passed by value, and if we mean thing 2, it is passed by reference. In both cases, name "listOne" is not correct name for thing 2 or thing 3, but it is used because it is short and convenient.

Alexei Kaigorodov
  • 13,189
  • 1
  • 21
  • 38
1

Java is pass by value.A copy of actual argument is passed to parameters.It is evident in case of primitive data types where changes in formal parameters is not shown in actual arguments.

 static void incre(int a)
      {
        a++;
      }
public static void main (String a[])
{ 
  int c=3;
  incre(c);
  System.out.println(c);  //still prints 3
}

Exact thing happens in case of references, but making a copy of reference does not create a new object, they both point to same object now.Hence changes made by references is reflected here.

class Demo { 
  int c =2; 

  Demo(int c)
    {
       this.c=c;
    } 

  void incObject (Demo x)    
    {
       (x.c)++;
    }

  int show()
   {
      return c;
   }
  public static void main (String []args)    
   {
    Demo o = new Demo(1);
    o.incObject(o);
   System.out.print(o.show()); //prints 2

 }

}
Malwaregeek
  • 2,274
  • 3
  • 15
  • 18
0
 Collections.reverse();

modifies the backing array. This is clear from the implementation:

 public static void reverse(List<?> list) {
        int size = list.size();
        if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) {
            for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--)
                swap(list, i, j);
        } else {
            ListIterator fwd = list.listIterator();
            ListIterator rev = list.listIterator(size);
            for (int i=0, mid=list.size()>>1; i<mid; i++) {
                Object tmp = fwd.next();
                fwd.set(rev.previous());
                rev.set(tmp);
            }
        }
    }

Now, listOne and listTwo have the same reference which points to the same backing array. So, no matter which handle(listOne or listTwo) modifies the backing array, the other will reflect the same changes. In your case:

    Collections.reverse(listOne);  // backing array has [3,2,1]
    listTwo = listOne;  //listTwo has same reference 
    Collections.reverse(listOne);  // backing array has [1,2,3]
    System.out.println(listOne);  //out put [1, 2, 3] 
    System.out.println(listTwo);  // same out put

As far as pass by value/reference is concerned. You said it yourself:

Java is pass by value, where values happen to be references.

why java try to avoid pass by reference and try to be different from some of other languages?

One of the main reasons would be that Java(JVM) manages its own memory.

Community
  • 1
  • 1
rocketboy
  • 9,573
  • 2
  • 34
  • 36
-2

Collections.reverse(listOne); passes the reference to listOne(the object) by value, which is how one defines "pass by reference". Everything other than primitives is passed this way: by reference. It does not try to avoid it, it is only different from C++ in that it doesn't explicitly use pointers.

EDIT: Okay, I think I see where you're coming from.

private static void changelist(List<Integer> list) {
    list.add(4);//This modifies the list object
    list = new ArrayList<Integer>();//This modifies the local copy of the reference to the list object
    list.add(5);
}
public static void main(String[] args) {
    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(3);
    System.out.println(list);//output is [1,2,3]
    //This copies the value of the reference. 
    //If you modify the object in the underlying 
    //function, changes will be preserved when you return
    //However if you modify what the reference points to,
    //the function will only modify the local copy
    changelist(list);
    System.out.println(list);//output is [1,2,3,4]

}
blgt
  • 8,135
  • 1
  • 25
  • 28
  • ok. Now java pass by reference or pass by value? – Ruchira Gayan Ranaweera Aug 15 '13 at 09:25
  • Java passes by reference anything other than a primitive type. An `int` is passed by value, while an `Integer` is passed by reference. The list objects in the code above are always passed by reference. – blgt Aug 15 '13 at 09:41
  • 2
    Although you've stated it in your answer, to make it perfectly clear in the comments, it's always the VALUE of the reference that is passed, not the reference itself. Everything in Java is pass by value. Everything! Primitive or object. – Andrew Martin Aug 16 '13 at 11:04
  • "passes the reference to listOne by value" No it doesn't. It passes `listOne` by value. – newacct Aug 16 '13 at 11:28
  • "passes the reference to listOne by value" <- Perhaps I am being a bit unclear with what I mean when I type in `listOne`: the object. I'll fix that. BUT: That is exactly what it does. The reference is passed the value, the object it references is passed by reference. Look up a definition of the term "pass-by-reference"; passing the reference by value is exactly what java does to achieve that. – blgt Aug 16 '13 at 12:23