Is Java parameter passing by value or by reference

Is Java parameter passing by value or by reference

  Regarding Java parameter passing by reference or by value, it has always been a topic of much discussion. Some people say that there is only value-passing in Java, and some people say that both value-passing and reference-passing exist, which makes it easier for people to question. Regarding passing by value and passing by reference, it needs to be viewed separately.

One, Java data types

Java data types are divided into two categories: "basic data types" and "reference types".

  • Basic data types (8 types)

Insert picture description here

  • Reference type (3 types)

  Reference types can be divided into class reference types (classes), interface reference types (interfaces), and array reference types (arrays). The following code defines 3 reference variables: user, myThread, and intArray.

User user;
java.lang.Runnable myThread;
int[] intArray;

  Among them, the user variable is a class reference type, the myThread variable is an interface reference type, and the intArray variable is an array reference type. The myThread variable is an interface reference type because java.lang.Runnable is an interface, not a class.

  A variable of the class reference type refers to an instance of this class or its subclasses, a variable of an interface reference type refers to an instance of a class that implements this interface, and a variable reference of an array reference type refers to an instance of this array type. In the Java language, arrays are also regarded as objects. This shows that no matter what kind of reference type variables, they refer to objects.

  If a reference type variable does not refer to any object, it can be assigned to null. When initializing a reference type variable, it is often assigned an initial value of null.

User user = null;

The parameters of the method are divided into actual parameters and formal parameters.

  • Actual parameter: the specific value written when the method is called.
  • Formal parameters: the parameters written when the method is defined.

  In general, when data is passed as a parameter, the basic data type is value transfer, and the reference data type is reference transfer (address transfer).

Two, value transfer

public static void main(String[] args) {
    
    
    int num1 = 100;
    int num2 = 200;
    take(num1, num2);
    System.out.println("num1 = " + num1);
    System.out.println("num2 = " + num2);
}

public static void take(int a, int b) {
    
    
    int temp = a;
    a = b;
    b = temp;
    System.out.println("a = " + a);
    System.out.println("b = " + b);
}

operation result:

a = 200
b = 100
num1 = 100
num2 = 200

Process

  1. The main function is pushed onto the stack, and num1 and num2 are initialized.
  2. Call the take method, take() into the stack, and copy the values ​​of num1 and num2 to a and b.
  3. In the take method, the values ​​of a and b are exchanged.
  4. The take method has finished running, and the values ​​of a and b have been exchanged.
  5. The take method pops the stack.
  6. The main function pops the stack.

Parsing

  In the take method, the values ​​of a and b are exchanged, and num1 and num2 are not affected. Because the values ​​in a and b are just copied from num1 and num2. That is to say, a and b are equivalent to copies of num1 and num2, and no matter how the content of the copy is modified, it will not affect the original itself.

Three, pass by reference

public static void main(String[] args) {
    
    
    int[] intArray = {
    
    1,2,3,4,5};
    change(intArray);
    System.out.println(intArray[0]);
}

public static void change(int[] array) {
    
    
    int len = array.length;
    array[0] = 0;
}

operation result:

0 

Process

  1. The main function is pushed onto the stack, and int[] intArray is initialized.
  2. Call the change method, change() into the stack, and copy the address value of intArray to array.
  3. In the change method, according to the address value, find the array in the heap and change the value of the first element to 0.
  4. The change method has finished running, and the value of the first element in the array has been changed.
  5. The change method pops the stack.
  6. The main function pops the stack.

Parsing

  When you call change(), the parameter array receives a copy of the intArray address value. And in the change method, the array is manipulated through the address value. After the change method pops the stack, the value in the array has changed. In the main method, the printed intArray[0] also changed from 1 to 0.

  Whether it is the main function or the change method, the operation is an array corresponding to the same address value.

  It's like you gave a key to your home to a babysitter. The babysitter gets the keys and cleans your house, and then leaves. When you return home with the key, the house has been completely new. The key here is equivalent to the address value, and the home is equivalent to the array itself.

String type transfer

public static void main(String[] args) {
    
    
    String str = "ABC";
    change(str);
    System.out.println(str);
}
public static void change(String a) {
    
    
    a = "DEF";
}

operation result:

ABC

  This is strange. String is a class, and the class is a class reference type. When passed as a parameter, it should be passed by reference. But from the result, it seems to be value passing.

the reason

  There is a sentence in the Api document of
Insert picture description here
  String : It means that the value of String cannot be changed after it is created.

  There is also a paragraph in Api:
Insert picture description here

String str = "abc"; 
// 相当于
char data[] = {
    
    'a', 'b', 'c'}; 
String str = new String(data); 

  That is to say, any modification to the String type str is equivalent to re-creating an object and assigning the new address value to str. In this case, the above code can be written like this:

public static void main(String[] args) {
    
    
    String str1 = "ABC";
    change(str1);
    System.out.println(str1);
}

public static void change(String a) {
    
    
    char data[] = {
    
    'D', 'E', 'F'};
    String str = new String(data);
    a = str;
}

Process

  1. The main function is pushed onto the stack and str1 is initialized.
  2. Call the change method, change () into the stack, and copy the address value of str1 to a.
  3. In the change method, a String object "DEF" is recreated, and a points to the new address value.
  4. After the change method is executed, the address value pointed to by a has changed.
  5. The change method pops the stack.
  6. The main function pops the stack.

Parsing

  When a String object is passed as a parameter, it is still passed by reference, but the String class is special.

  Once the String object is created, the content cannot be changed, and every content change is a new object created again.

  When the change method is executed, the address value pointed to by a has changed, and the original address value of a is a copied copy, so the value of str1 cannot be changed.

Similar to String type

class User {
    
    
    String name;
    public User(String name) {
    
    
        this.name = name;
    }
}

public static void main(String[] args) {
    
    
    User user = new User("张三");
    change(user);
    System.out.println(user.name);
}

public static void change(User u) {
    
    
    User user = new User("李四");
    u = user;
}

operation result:

张三

to sum up

  • Java basic data types are passed by value when passing parameters; when they are passed by reference types, they are passed by reference.
  • When passing by value, pass the value of the actual parameter to the formal parameter; when passing by reference, pass the address value of the actual parameter to the formal parameter.
  • When the value is passed, it is the argument values passed to a corresponding parameter, the function receives a copy of the original value, at this time there are two basic types are equal, i.e., arguments and parameters in memory , after the method of The operation is to modify the value of the formal parameter, and does not affect the value of the actual parameter . When passing by reference, the reference of the actual parameter (address, not the value of the parameter) is passed to the corresponding formal parameter in the method, and the function receives the memory address of the original value; in the execution of the method, the contents of the formal parameter and the actual parameter are the same , Point to the same memory address, the operation of the reference in the execution of the method will affect the actual object.
  • Special consideration needs to be given to String and Integer, Double and other basic type packaging classes. They are all immutable types. Because there is no function to modify themselves, each operation creates a new object, so special treatment is required. Because the final operation does not modify the actual parameters, it can be considered as similar to the basic data type and is passed by value.

Guess you like

Origin blog.csdn.net/qq_42647711/article/details/109214744