Comprehensive understanding of reference passing and value passing in Java

  • 2021-12-04 10:15:03
  • OfStack

Directory 1. Basic type and reference type in memory saving 2. Variable basic type and reference type difference 3. Reference passing and value passing 4. Conclusion

It is a topic that has been discussed a lot about whether Java passes parameters by reference or value.

Some people say that there is only value passing in Java, and some places say that both reference passing and value passing exist. This article records the thinking process and does not guarantee the correctness.

Interested students have a discussion.

1. Storage of primitive and reference types in memory

Data types in Java are divided into two categories, basic types and object types. Correspondingly, there are two types of variables: basic type and reference type.

The basic type of variable holds the original value, that is, the value it represents is the value itself;

While variables of reference type hold reference values, "reference values" point to the address of the memory space and represent a reference to an object rather than the object itself,

The object itself is stored at the address represented by this reference value.

Basic types include: byte, short, int, long, char, float, double, Boolean, returnAddress,

Reference types include: class types, interface types, and arrays.

Correspondingly, there are two types of variables: basic type and reference type.

2. Differences between basic types and reference types of variables

The system allocates space for the basic data type when it is declared:


int a;
a=10;// Correct, because the statement a Space is allocated when 

References, on the other hand, are declared only by allocating reference space to variables, but not data space:


Date date;
// Execute instantiation and open up data space storage Date Object, and then passes the first address of the space to the today Variable  
//date=new Date();
// If the comment is dropped on 1 Step operation 
//The local variable date may not have been initialized
// That is to say, the data space of the object is not allocated 
date.getDate();

Look at the following initialization procedure under 1, and note that "reference" also takes up space. The reference size of an empty Object object is about 4byte:


Date a,b; // Open up two reference spaces in memory 
a = new Date();// Open up storage Date Object, and assigns the first address of the space to the data space of the a
b = a; // Will a The address in the storage space is written to b In the storage space of 

3. Reference passing and value passing

Here, we should use the concepts of actual parameters and formal parameters to help us understand.

Value passing:

When the method is called, the actual parameter passes its value to the corresponding formal parameter, and the function receives one copy of the original value. At this time, there are two equal basic types in memory, namely the actual parameter and the formal parameter. The operations in the following methods are all modifications to the value of the formal parameter without affecting the value of the actual parameter.

Reference passing:

Also known as mailing. When the method is called, 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 method execution, the formal parameter and argument have the same content and point to the same block of memory address. The operation of reference in method execution will affect the actual object.

Look at an example:


class MyObj{
    public int b=99;
}

Refer to int and object type respectively:


public class ReferencePkValue2 {
     
    public static void main(String[] args) { 
        ReferencePkValue2 t = new ReferencePkValue2(); 
        int a=99; 
        t.test1(a);// The parameters passed here a Is passed by value  
        System.out.println(a);
         
        MyObj obj=new MyObj(); 
        t.test2(obj);// The parameters passed here obj Is reference passing 
        System.out.println(obj.b);
    } 
     
    public void test1(int a){ 
        a=a++;
        System.out.println(a);
        } 
     
    public void test2(MyObj obj){ 
        obj.b=100;
        System.out.println(obj.b);
        }
}

The output is:

99

99

100

100

You can see that the int value has not changed, but the modifications made to the obj class in the test2 method affect the obj object.

Special consideration should be given here to String, and several basic type wrapper classes such as Integer and Double, which are all immutable types.

Because there is no function to modify itself, every operation is a new object, so it should be treated specially, which can be considered as a value-passing operation similar to the basic data type.

Look at the following example:


public class ReferencePkValue1 {
    public static void main(String[] args){
        ReferencePkValue1 pk=new ReferencePkValue1();
        //String Similar to basic types, value passing does not change the value of actual parameters 
        String test1="Hello";
        pk.change(test1);
        System.out.println(test1);
         
        //StringBuffer And StringBuilder And so on are reference passing 
        StringBuffer test2=new StringBuffer("Hello");
        pk.change(test2);         
        System.out.println(test2.toString());
    }
     
    public void change(String str){
        str=str+"world";
    }
     
    public void change(StringBuffer str){
        str.append("world");
    }
}

The output is:

Hello

Helloworld

The operation of String and StringBuffer produced different results.

4. Conclusion

Combined with the above analysis, we can draw the following conclusions about value passing and reference passing:

(1) The basic data type is passed by value, and the modification of formal parameters will not affect the actual parameters;

(2) The reference type is passed by reference, and the formal parameter and the actual parameter point to the same memory address (the same object), so the modification of the parameter will affect the actual object;

(3) The special treatment of immutable, such as String, Integer and Double, can be understood as passing values, and the final operation will not modify the argument object.


Related articles: