Before reading this article, based on your own experience and understanding, you can first think about and choose the parameter passing method of Java functions:
A. Is it passed by value?
B. Passed by reference?
C. Partly by value and partly by reference?
The correct answer will not be announced here for the time being. We will use a simple example to let everyone find the answer by themselves:
1. First define a type Value
public static class Value { private String value = "value"; public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
2. Write two There are two functions, newValue and modifyValue: newValue will point the input parameter to a new object, and modifyValue will call the setValue method of the input parameter to modify the value of the object.
public static void newValue(Value value) { value = new Value(); value.setValue("new value"); System.out.println("In newValue, HashCode = " + value.hashCode() + ", value = " + value.getValue()); } public static void modifyValue(Value value) { value.setValue("new value"); System.out.println("In modifyValue, HashCode = " + value.hashCode() + ", value = " + value.getValue()); }
3. Simple test code
public static void main(String[] args) { Value value1 = new Value(); System.out.println("Before modify, HashCode = " + value1.hashCode() + ", value = " + value1.getValue()); // 将value1指向新的Value对象 newValue(value1); System.out.println("After modify, HashCode = " + value1.hashCode() + ", value = " + value1.getValue() + "\n"); Value value2 = new Value(); System.out.println("Before modify, HashCode = " + value2.hashCode() + ", value = " + value2.getValue()); // 使用object的set方法,修改对象的内部值 modifyValue(value2); System.out.println("After modify, HashCode = " + value2.hashCode() + ", value = " + value2.getValue()); }
4. Execution result log:
Before modify, HashCode = 12677476, value = value In newValue, HashCode = 33263331, value = new value After modify, HashCode = 12677476, value = value Before modify, HashCode = 6413875, value = value In modifyValue, HashCode = 6413875, value = new value After modify, HashCode = 6413875, value = new value
5. Result analysis:
The above code is a very common programming pattern: define | save | get a value or object in the periphery, pass the object as a parameter into a method, and modify the properties and behavior of the object in the method. However, the modification methods of the two methods newValue and modifyValue are different. After the method is called, the object looks very different from the outside! How to understand this difference? Let’s first review the concepts of pass by value and pass by reference:
* Pass by value means that when a parameter is passed to a function, the function receives a copy of the original value. Therefore, if the function modifies the parameter, only the copy is changed, while the original value remains unchanged.
* Passing by reference means that when you pass an argument to a function, the function receives the memory address of the original value, not a copy of the value. Therefore, if the function modifies the parameter, the original value of the parameter (in the calling code outside the function block) also changes.
Correct answer: A——Java functions pass parameters by value!
Analyze the log:
* In the first log output, the value1 parameter is changed to point to a new object inside the newValue method, and the hashCode and value of the new object are output, but after jumping out of the newValue method domain, in the main There is no change in value1 in the method, which is consistent with the definition and characteristics of passing by value; if it is passed by reference, value1 should change after calling the newValue(Value value) method.
* In the second log output, value2 performs a setValue operation inside the modifyValue method. The hashCode remains unchanged but the value is modified. After leaving the modifyValue method domain, value2 does change in the main method. People who have used C++ can easily understand this phenomenon as: passing function parameters by reference! Because this is very similar to pass by reference in C++! But this is exactly where it is most likely to fall into misunderstandings!
The principle behind the different phenomena of the two logs is that the Java language passes parameters by value and objects by reference; the objects operated in Java are actually references to the operating objects, and the object itself is stored in " Heap", while the object's "reference" is stored in a register or "stack".
Pseudo code describes the difference between the newValue method and the modifyValue method:
newValue{ Value_ref2 = value_ref1; // 按值传入引用value_ref1,得到value_ref1的副本 value_obj2 = new Value(); // value_obj2被创建、初始化在“堆“中 value_ref2 -> value_obj2; // value_ref2 指向value_obj2 value_ref2 ->value_obj2.setValue(“xxx”); // value_obj2 的value被修改 printValueObj2(); // 此处打印的是obj2的值 } modifyValue{ Value_ref2 = value_ref1; // 按值传入引用value_ref1,得到value_ref1的副本 value_ref2 ->value_obj1.setValue(“xxx”); // value_obj1 的value被修改 printValueObj1(); // 此处打印的是obj1的值 }
It’s clear enough! When value1_ref1 is passed into the function as a parameter, a copy of value1_ref2 is first copied for use in the function domain. At this time, both refs point to the same value_obj; code in the newObject function [value = new Value(); ] In fact, value1_ref1 points to a new object value_obj2; the set operations after this are all operations on the new object; the modifyValue function directly operates value_obj1 through the set method, which is different from the newValue function.
Passing parameters by value
When calling a method, you need to provide parameters. You must provide them in the order specified in the parameter list.
For example, the following method prints a message n times in succession:
public static void nPrintln(String message, int n) { for (int i = 0; i < n; i++) System.out.println(message); }
Example
The following example demonstrates the effect of passing by value.
This program creates a method that is used to exchange two variables.
public class TestPassByValue { public static void main(String[] args) { int num1 = 1; int num2 = 2; System.out.println("Before swap method, num1 is " + num1 + " and num2 is " + num2); // 调用swap方法 swap(num1, num2); System.out.println("After swap method, num1 is " + num1 + " and num2 is " + num2); } /** 交换两个变量的方法 */ public static void swap(int n1, int n2) { System.out.println("\tInside the swap method"); System.out.println("\t\tBefore swapping n1 is " + n1 + " n2 is " + n2); // 交换 n1 与 n2的值 int temp = n1; n1 = n2; n2 = temp; System.out.println("\t\tAfter swapping n1 is " + n1 + " n2 is " + n2); } }
The compilation and running results of the above example are as follows:
Before swap method, num1 is 1 and num2 is 2 Inside the swap method Before swapping n1 is 1 n2 is 2 After swapping n1 is 2 n2 is 1 After swap method, num1 is 1 and num2 is 2
Pass two parameters to call swap method. Interestingly, the values of the actual parameters do not change after the method is called.
For more in-depth analysis of parameter passing of methods in Java programming, please pay attention to the PHP Chinese website!