Location>code7788 >text

Is Java value or reference passing and how does it manifest itself

Popularity:761 ℃/2024-09-07 17:02:41

Regarding whether Java is value passing or reference passing, you can implement it from the code level to get the result
Execute the following code:

    public static void main(String[] args) {
        String name = "Tom"; String
        String name = "Tom"; modify(num, name); { int
        modify(num, name);
        ("3rd print int:" + num);
        ("3rd print of String: " + name); modify(num, name); modify(name)
        ("------------------------------------");
    }

    public static void modify(int n, String str){
        ("1st print of int: " + n); } public static void modify(int, String str){
        ("1st print String: " + str); } public static void modify(int n, String str){ ("1st print int: " + n); }
        ("------------------------------------");

        // Try to modify the passed-in parameters inside the method
        n = 999; str = "ABC"; (""); // Try to modify the incoming parameters inside the method.
        str = "ABC"; ("2nd print of String: " + str); (""); // Try to modify the incoming parameters inside the method.
        ("Print int for the 2nd time: " + n);
        ("Print String for the 2nd time: " + str);
        ("------------------------------------");
    }

The printout is as follows:

1st print int: 10
1st print String: tom
------------------------------------
2nd print int: 999
2nd printing String: ABC
------------------------------------
3rd print int: 10
3rd printing of String: Tom
------------------------------------

You can see that whether it is a basic type or a reference type, the value of the parameter passed in is the same as the value after executing the modify method, that is, the first print and the third print are the same. However, why is it that the value has been modified successfully in the 2nd time, and then changed back in the 3rd time?
Trying to take out the parameters in a different way, the

    public static void main(String[] args) {
        String name = "Tom"; String
        
        String modifiedNum = modifyAndReturn(num); String modifiedName = modifyAndReturn(name);
        String modifiedName = modifyAndReturn(name);
        ("Printing num: " + num);
        
        ("------------------------------------");
        
        
    }

    public static int modifyAndReturn(int n){
        ("modifyAndReturn 1st print int:" + n); }

        // Try to modify the passed-in parameters inside the method
        n = 999; // Try to modify the passed in parameters inside the method.
        ("modifyAndReturn 2nd print int: " + n); // Try to modify the passed in parameters inside the method.
        ("------------------------------------");
        return n; }
    }

    public static String modifyAndReturn(String str){
        ("modifyAndReturn 1st print of String:" + str);

        // Try to modify the incoming parameters inside the method
        str = "ABC";
        ("modifyAndReturn 2nd print of String: " + str); // Try to modify the incoming parameters inside the method.
        ("------------------------------------"); // Try to modify the incoming parameters inside the method.
        return str; }
    }

The results obtained are

modifyAndReturn 1st print int: 10
modifyAndReturn 2nd print int: 999
------------------------------------
modifyAndReturn 1st print String: Tom
ModifyAndReturn 2nd Print String: ABC
------------------------------------
Print num: 10
Print name: Tom
------------------------------------
Print modifiedNum: 999
Print modifiedName: ABC

You can see that the value returned is indeed changed, so why is the change not applied to the parameter body? Modify the code to test again

public static void main(String[] args) {
        String name = "Tom"; String
        String name = "Tom";
        // Print the address of num and str
        ("Before modifying, before passing the parameter: "); ((num));; ("Before modifying, before passing the parameter:")
        ((num)).
        ((name));

        ("---------------------------");
        printAddr(num, name);

        ("---------------------------");
        ("After modifying and executing the method:");
        ((num)); (""); printAddr(name)
        ((name));
    }

    public static void printAddr(int n, String str){
        // Print the address of n and str
        ("Before modification, after passing parameter:"); }
        ((n)).
        ((str));

        n = 999;
        str = "ABC";

        // Print the address of n and str
        ("---------------------------");
        ("Modified, after passing the parameter:");
        ((n)); // Print the address of n and str.
        ((str));
    }

The results of the implementation are as follows

Before modification, before passing the reference:
1324119927
990368553
---------------------------
Before modification, after passing the reference:
1324119927
990368553
---------------------------
Modified, after passing the reference:
1096979270
1078694789
---------------------------
Modified, after executing the method:
1324119927
990368553

You can see that the address of the parameter passed in is the same as the externally defined address, but after the modification will point to another new address, resulting in the original address of the data will not be affected, which is in fact a protection mechanism to prevent the parameter passed into the method to be tampered with pointing.

The following demonstrates another case of reference types, which some old-timers may think is a modification of the reference type itself, which is actually not true.
First define a class Person

class Person{
    private String name;
    private int age;

    public Person(String name, int age) {
         = name;
         = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
         = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
         = age;
    }

	@Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }	
}

Execute the following code to see the properties of the passed-in parameters changed


    public static void main(String[] args) {
        Person person = new Person("Rosy", 24);
        String [] strings = {"AAA", "BBB", "CCC"}
        ("1st print:");
        (person);
        ((strings));

        modifyObjAndPrintValue(person, strings);

        ("---------------------------");
        ("4th print:");
        (person).
        ((strings));
    }

    public static void main5(String[] args) {
        Person person = new Person("Rosy", 24);
        String [] strings = {"AAA", "BBB", "CCC"}; }
        ("1st print:");
        ((person)).
        ((())); ((())).
        
        ((strings)); ((strings)).

        modifyObj(person, strings).

        ("---------------------------");
        ("4th print:");
        ((person)).
        ((())); (((person))); ((person)); ((person)); ((person))
        
        ((strings)); ((strings))
    }

    public static void modifyObjAndPrintValue(Person person, String [] strings){
        ("---------------------------");
        ("2nd print:");
        (person);
        ((strings)).

        (1024); ("ABC")
        ("ABC");
        strings[0] = "XXX";

        ("---------------------------");
        ("3rd print:");
        (person);
        ((strings));
    }

The result of the execution is

1st print:
Person{name='Rosy', age=24}
[AAA, BBB, CCC]
---------------------------
2nd print:
Person{name='Rosy', age=24}
[aaa, bbb, ccc]
---------------------------
3rd print:
Person{name='ABC', age=1024}
[xxx, bbb, ccc]
---------------------------
4th print:
Person{name='ABC', age=1024}
[xxx, bbb, ccc]

From the results, we can find that the properties of the Person object are modified, and the elements of the String array are also modified, indicating that the parameter changes to the properties or array will affect the object itself, you can print the address to check again:


    public static void main(String[] args) {
        Person person = new Person("Rosy", 24);
        String [] strings = {"AAA", "BBB", "CCC"}
        ("1st print:");
        ((person)).
        ((())); ((())).
        
        ((strings)); ((strings[0])); ((strings[0]))
        ((strings[0])); ((strings[0])).

        modifyObjAndPrintAddr(person, strings);

        ("---------------------------");
        ("4th print:");
        ((person)).
        ((()))); ((())); ("4th print: "); ((person)).
        ((()))); (((strings))).
        ((strings)); ((strings[0])); ((strings[0])).
        ((strings[0])); ((strings[0])); ((strings[0])).
    }


    public static void modifyObjAndPrintAddr(Person person, String [] strings){
        ("---------------------------");
        ("2nd Print:");
        ((person)).
        ((())); ((())).
        ((()))); ((strings)); ((strings)); ((strings)); ((strings))
        ((strings)); ((strings[0])); ((strings[0])).
        ((strings[0])).

        (1024); ((strings[0])); ((strings[0]))
        ("ABC");
        strings[0] = "XXX";

        ("---------------------------");
        ("3rd print:");
        ((person)); ((person)); ((person)); ((person)); ((person))
        ((()))); (((person))); ((person)); ((person)); ((person))
        
        ((strings)); ((strings[0])); ((strings[0])).
        ((strings[0])); ((strings[0])); ((strings[0])).
    }
1st Printing:
990368553
1096979270
1078694789
1831932724
1747585824
---------------------------
2nd Printing:
990368553
1096979270
1078694789
1831932724
1747585824
---------------------------
3rd Printing:
990368553
1023892928
558638686
1831932724
1149319664
---------------------------
4th Printing:
990368553
2093631819
558638686
1831932724
1149319664

As you can see from the address, the address of person and strings has never changed. Instead, the person attribute and the array element, which are modified inside the parameter, will modify the address of this part of the member and will be applied to the object ontology.

To summarize is that, regardless of whether the pass is a basic type or reference type, as long as the method within the attempt to change the address of the parameter, can only be used within the method, will not affect the ontology, and in the method within the change of attributes, the corresponding changes will be applied to the ontology. So Java is value-passing, when you pass a parameter, you don't pass in the parameter itself, but you create a copy of it, so that when it's pointed to by a modification, it doesn't affect itself, and when you change a property, you don't change the address of the property itself, so it can be applied to the body.