After the object is passed into the method and assigned in Java, why does the value of the object not change after the method is executed?

Problem background:

When testing the interface written by my colleagues yesterday, I found such a problem

The first step in the figure above: lhygTaskMode = null, and then pass it into the checkParam method for assignment. After the last method is executed, lhygTaskMode is still null. Why?

problem causes:

Because java has only one way to pass parameters: value passing .

In value passing, the value of the actual parameter is passed to the formal parameter, and any assignment operation to the formal parameter in the method body will not affect the actual parameter.

Test case:

Next, we simply write a test case to see the specific output.

public class Test {
    
    private String name;
    

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public static void main(String[] args) {
        Test a = null;
        changeObj(a);
        System.out.println(a);
    }
    public static void changeObj(Test a) {
        a = new Test();
        System.out.println("changeObj>>"+a);
    }

}

The output of executing the above code is as follows:

It can be seen that after the internal object of the method is assigned, the object address is output, but after the method is executed, the source object a is still null.


Next, let's test again, the output result after modifying the attribute value of the source object.

package com.btonline365.support.test;

public class Test {
    
    private String name;
    

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public static void main(String[] args) {
//        Test a = null;
//        changeObj(a);
//        System.out.println(a);
        
        Test a = new Test();
        a.setName("王五");
        changeObjValue(a);
        System.out.println(a.name);
    }
    public static void changeObj(Test a) {
        a = new Test();
        System.out.println("changeObj>>"+a);
    }
    
    public static void changeObjValue(Test a) {
        a.setName("李四");
        System.out.println("changeObjValue>>"+a.name);
    }
}

The output is as follows:

Here the attribute value changed from Wang Wu to Li Si.


Then in the second test, the attribute value of the formal parameter was modified. Why did the formal parameter modify the attribute value of the actual parameter by the way?

Any assignment operation to the formal parameter will not affect the actual parameter, but the assignment operation to the field of the formal parameter, or the element (if the formal parameter is an array) will affect the actual parameter.

Supplementary Note:

Passing by value refers to copying the actual parameters to the function when calling the function, so that if the parameters are modified in the function, the actual parameters will not be affected.

Passing by reference means that the address of the actual parameter is directly passed to the function when the function is called, then the modification of the parameter in the function will affect the actual parameter.

So, let me summarize for you what is the key point of the difference between passing by value and passing by reference.

pass by value

pass by reference

fundamental difference

will create a copy

do not create a copy

all

The original object cannot be changed in the function

The original object can be changed in the function

Scenario description:

If you have a key, when your friend wants to come to your house, if you just give him your key, this is pass-by-reference. In this case, if he does something to the key, such as engraving his name on the key, when the key is returned to you, your own key will also have his engraved name on it.

You have a key. When your friend wants to go to your house, you forge a new key for him, and your own is still in your hand. This is value transfer. In this case, nothing he does to the key will affect the key in your hand.

However, regardless of the situation above, your friend took the key you gave him, entered your house, and smashed your TV. So you say you will not be affected?

    public static void main(String[] args) {
        Test a1 = new Test();
        System.out.println("源对象初始地址:"+a1);
        changeObj(a1);
        System.out.println(a1);

    }
public static void changeObj(Test a) {
        a = new Test();
        System.out.println("changeObj>>"+a);
    }

It can be seen above that the address value of the object has not changed.

Explain this picture a little bit. When we create a Test object in main, we open up a piece of memory in the heap. A1 then holds the address @15db9742 of that memory (Figure 1). When trying to call the changeObj method, and a1 is passed as the actual parameter to the formal parameter a, the address @15db9742 will be given to a, and at this time, a also points to this address (Figure 2). Then when the parameters are modified in the changeObj method, that is, a=new Test();, a piece of @6d06d69c memory will be re-opened and assigned to a. Any subsequent modifications to a will not change the contents of memory @15db974 (Figure 3).

What is the above transfer? It is definitely not a reference transfer. If it is a reference transfer, when a=new Test(), the reference of the actual parameter should also be changed to point to @15db974, but in fact it does not .

Through the concept, we can also know that here is to copy the address of the reference of the actual parameter and pass it to the formal parameter. Therefore, the above parameters are actually passed by value, and the address referenced by the actual parameter object is passed as a value to the formal parameter.

So, the difference between pass by value and pass by reference is not what is passed. It is whether the actual parameter is copied to the formal parameter. When judging whether the content of the actual parameter is affected, it depends on what is passed. If you pass an address, then it depends on whether the change of the address will affect it, not the change of the object pointed to by the address. It's like the relationship between a key and a house.

所以说,Java中其实还是值传递的,只不过对于对象参数,值的内容是对象的引用。

Guess you like

Origin blog.csdn.net/weixin_36754290/article/details/129548720