Why doesn't the primitive wrapper class change after passing as an argument?

Ok I fully understand 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 pass the wrapper class to the changeInteger method, I pass its address, so after executing a function that should affect my variable x and set it to 5. But eclipse says that the output is still 0. What do I understand wrong?

+8
java
source share
6 answers

Consider the following 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 replace the 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 it is clear why this code does what it does.

Now back to your code. Under the hood, this is exactly the same code. The only difference is that you are not calling Wrapper.valueOf : the compiler does this for you through autoboxing. Once you realize that this is what is happening, the problem should be clear to you.

ByteCode changeInteger() to show that Integer.valueOf() is being 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 
+4
source share

C x = 5; you assign a new value to x inside changeInteger() . You do not change the value of the current Integer object.

The value of x outside the method does not affect.

+4
source share

Your problem is that Java is passing by value, not a reference, so the x in the method does not match the main x . The fact that Integer is an immutable class does not change anything here.

+2
source share

You are puzzled by the java auto-boxing feature. You cannot assign a primitive value to an object. When you call x=5 , it creates a new Integer object with a value of 5 and assigns its reference x . But this only affects the parameter in the changeIngeger , the original object with 0 and the reference to x in the main area are not affected.

+2
source share

All Java parameters are passed by value. For all non-primitive types, the value contains a reference to the passed object.

For your piece of code, an Integer object is stored in cell A in memory. Another place B in memory represents the variable main x and stores the value of A

To call changeInteger , a new C location is created, and the value in B (which is A ) is copied to it. This is the local x function of the changeInteger function.

Upon assignment, you create a new variable stored in D , and its location is assigned to C Then you return from the method.

You can see that A and B do not change anywhere, so the value remains unchanged.

+1
source share

Keeping everything you want, all Java Wrapper classes are Immutable . So you do not see the change.

If you want to see the change, just go back from the method (not main) and assign it back.

0
source share

All Articles