0

The following code is printing out values which are unexpected to me; the code is printing out 50 and then 19. Below I have set out my reasoning, please can someone correct the error in my reasoning process:

class Wrapper{
    int w = 10;
}

public class Main {
    static Wrapper changeWrapper(Wrapper w){
        w = new Wrapper();
        w.w += 9;
        return w;
    }
    public static void main(String[] args) {
        Wrapper w = new Wrapper(); // line 1
        w.w = 20; // line 2
        changeWrapper(w); // line 3
        w.w += 30; // line 4
        System.out.println(w.w); // line 5
        w = changeWrapper(w); // line 6
        System.out.println(w.w);  // line 7
    }
}

Reasoning Process:

  1. At line 1, a new Wrapper object is created and the value of w.w is 10.
  2. At line 2, the value of w.w is set to 20.
  3. At line 3, a reference to w is passed to the changeWrapper function. In the changeWrapper function, a new Wrapper object is created and assigned to the passed in reference. So now, w is pointing to a new Wrapper object and so the value of w is 10. Nine is added to this value and an object is returned with w.w equal to 19.
  4. At line 4, 30 is added so now w.w is 49.
  5. At line 5, 49 should be printed out.
  6. At line 6, the Wrapper object with w.w equal to 49 is passed to the changeWrapper method. Inside that method, a new Wrapper object is created and an object is returned with the value of w.w set to 19. This reference to this object is then assigned to w. So now w points to an object with w.w set to 19. So, 19 is printed out as expected.

Why is 50 printed out instead of 49?

7 Answers7

1

java is pass by value, so changeWrapper is not overriding w with a new wrapper in the main method.

changeWrapper method does not in anyway effect the reference to wrapper in you main method.

This will do what you expect, using only one reference to the orginal Wrapper that was created :

static Wrapper changeWrapper(Wrapper w){
  w.w += 9;
  return w;
}

As the orginal reference to w is passed in, you can alter its values. Whereas your code simply creates a new reference to a new object. btw change your naming convention.

NimChimpsky
  • 46,453
  • 60
  • 198
  • 311
  • Ok, I thought Java passed by reference to methods. It's not my naming convention. It's a question from a Java certification exam. –  Jun 04 '14 at 10:37
  • the orginial reference to w is passed into method, however it is overridden by another new Wrapper - the original reference to w in main method is not effected. Have a look on this site for java pass by value. – NimChimpsky Jun 04 '14 at 10:39
  • two references one local to change wrapper, the other local to main and only one object on the heap. When you do the new Wrapper you can create a second object on heap. – NimChimpsky Jun 04 '14 at 11:03
  • I just saw this post: http://stackoverflow.com/a/73021/3248346 - I understand it now. Cheers –  Jun 04 '14 at 11:04
1

You're assigning a new instance of Wrapper to the reference of the argument in your changeWrapper method and returning it.

As such, the w of your returned Wrapper is 19.

This doesn't change the passed object, only the reference within method's scope, and of course, the returned object.

However, you are assigning that returned Wrapper instance with w == 19 to the w local variable of your main method.

Remove w = new Wrapper(); from changeWrapper.

To recap (scope within main method)

  • Line 3 doesn't do anything to w
  • Line 6 changes w.w to 19
Mena
  • 47,782
  • 11
  • 87
  • 106
0

Problem is with :

  static Wrapper changeWrapper(Wrapper w){
        w = new Wrapper(); // this line
        w.w += 9;
        return w;
    }

Remove this assignment and it should work as you expect

Sanjeev
  • 9,876
  • 2
  • 22
  • 33
0
static Wrapper changeWrapper(Wrapper w){
        w = new Wrapper(); // this line create new refrence of wrapper class so overrise w which you get in method variable
        w.w += 9;
        return w;
    }
Rishi Dwivedi
  • 908
  • 5
  • 19
0

In java- References to Objects are passed by Value. So,

public static void main(String[] args) {
    Wrapper w = new Wrapper(); // line 1. w-->wrapper object
    w.w = 20; // line 2  
    changeWrapper(w); // line 3
    w.w += 30; // line 4
    System.out.println(w.w); // line 5. 20+30=50
    w = changeWrapper(w); // line 6. see method comments
    System.out.println(w.w);  // line 7
}



static Wrapper changeWrapper(Wrapper w){// w(1) and w(2) both point to same wrapper.
        w = new Wrapper();  //w(1)--> original wrapper passed. w(2 i.e, the w in your method)--> new wrapper object
        w.w += 9;
        return w; //returns new wrapper. 
    }
TheLostMind
  • 35,966
  • 12
  • 68
  • 104
0

Line 3 is not doing what you say it is!

At line 3, a reference to w is passed to the changeWrapper function. In the changeWrapper function, a new Wrapper object is created and assigned to the passed in reference.

Ok.

changeWrapper(w); // line 3

So now, w is pointing to a new Wrapper object and so the value of w is 10. Nine is added to this value and an object is returned with w.w equal to 19.

This is where you went wrong. An instance is returned but you are not assigning it to w. Therefore w still points to the old instance which has w of 20 not 19.

Si Kelly
  • 703
  • 3
  • 9
0
public static void main(String[] args) {
    Wrapper w = new Wrapper(); // line 1
    w.w = 20; // line 2
    w=changeWrapper(w); // line 3 
    w.w += 30; // line 4
    System.out.println(w.w); // line 5 This will give 49
    w = changeWrapper(w); // line 6
    System.out.println(w.w);  // line 7
}

changeWrapper(w); // line 3 
This will not do anything to w

w=changeWrapper(w); // line 3 
Do changes on w
R D
  • 1,330
  • 13
  • 30