Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why primitive wrapper class does not change after passing as an argument? [duplicate]

Tags:

java

Ok. I'm completely aware that all values in Java are passed by value. But this example does not behave as I expected:

public class Test {

private static void changeInteger(Integer x) {
    x = 5;
}

public static void main(String[] args) {
    Integer x = 0;
    changeInteger(x);
    System.out.println(x);
}

}

Since I'm passing wrapper class to the changeInteger Method, I'm passing its address, so, after executing function that should affect my x variable and set it to 5. But eclipse says that output is still 0. What did I understand wrong?

like image 955
Filip Avatar asked Sep 16 '14 10:09

Filip


1 Answers

Consider this example:

class Wrapper {
    int n;
    public Wrapper(int k) { n = k; }
    public String toString() { return ""+n;}
    public static Wrapper valueOf(int k) { return new Wrapper(k); }
}

Now let us replace Integer in your code with the Wrapper class above:

private static void changeInteger(Wrapper x) {
    x = Wapper.valueOf(5);
}

public static void main(String[] args) {
    Wrapper x = Wrapper.valueOf(0);
    changeInteger(x);
    System.out.println(x);
}

Since you mentioned that you know about passing by value, I hope that it is clear why this code does what it does.

Now let's go back to your code. Under the hood, it is exactly the same code. The only difference is that you do not call Wrapper.valueOf: the compiler does it for you through autoboxing. Once you realize that this is what is going on, the issue should be clear to you.

ByteCode of changeInteger() to show that Integer.valueOf() is called :

private static void changeInteger(java.lang.Integer);
  Code:
   Stack=1, Locals=1, Args_size=1
   0:   iconst_5
   1:   invokestatic    #16; //Method java/lang/Integer.valueOf:(I)Ljava/lang/In
  teger;
  .... // some other code
like image 160
Sergey Kalinichenko Avatar answered Nov 04 '22 09:11

Sergey Kalinichenko