Intopass
Links: https://www.zhihu.com/question/31203609/answer/50992895
Source: Know
Copyright belongs to the author. Commercial reprint please contact the author for authorization, non-commercial reprint please specify the source.
First, do not dwell on the literal meaning of pass by Value and pass by Reference, otherwise it is easy to fall into the so-called "all references in essence is the value of the transfer" This does not solve the problem of meaningless controversy.
What's more, if you want to know whether Java is a value or a reference, at least you have to know the value of the transfer and the exact meaning of the reference it? But if you already know the exact meaning of these two names, then you can judge whether Java is a pass or a reference.
It's like using a college term to explain a high school topic that doesn't make any sense to beginners.
First, to understand the differences between the basic type and the reference type
int num = 10;String str = "hello";
<img data-rawheight= "458" src= "https://pic3.zhimg.com/50/ 166032bc90958c21604110441ad03f45_hd.jpg "data-size=" normal "data-rawwidth=" 728 "class=" origin_image Zh-lightbox-thumb "width=" 728 "data-original=" https://pic3.zhimg.com/166032bc90958c21604110441ad03f45_r.jpg " >
, num is the base type, and the value is stored directly in the variable. While STR is a reference type, the variable holds only the address of the actual object. This variable is generally referred to as a "reference", a reference to the actual object, and the contents stored in the actual object.
Second, make clear the function of the assignment operator (=)
num == "Java";
<img data-rawheight= "572" src= "https://pic4.zhimg.com/50/ 287c0efbb179638cf4cf27cbfdf3e746_hd.jpg "data-size=" normal "data-rawwidth=" 714 "class=" origin_image Zh-lightbox-thumb "width=" 714 "data-original=" https://pic4.zhimg.com/287c0efbb179638cf4cf27cbfdf3e746_r.jpg " >
For the base type num, the assignment operator changes the value of the variable directly, and the original value is overwritten.
For reference type STR, the assignment operator changes the address saved in the reference, and the original address is overwritten. but the original object will not be changed (important).
As shown, the "Hello" string object has not been changed. (objects that are not pointed to by any reference are garbage and are recycled by the garbage collector)
Iii. what happens when a method is called?
parameter passing is basically an assignment operation 。
第一个例子:基本类型
void foo (int value) { =+// num not changed
第二个例子:没有提供改变自身方法的引用类型
void foo (String text) { = "Windows"// str has not been changed
第三个例子:提供了改变自身方法的引用类型
New StringBuilder ("iphone"); void foo (StringBuilder builder) { builder.append ("4"// SB was changed and became "iphone4".
第四个例子:提供了改变自身方法的引用类型,但是不使用,而是使用赋值运算符。
New StringBuilder ("iphone"); void foo (StringBuilder builder) { new StringBuilder ("ipad"// SB has not been changed, or " iphone ".
Focus on understanding why, the third example and the fourth example results in a different result?
The following is a schematic of the third example:
<img data-rawheight= "398" src= "https://pic2.zhimg.com/50/ D8b82e07ea21375ca6b300f9162aa95f_hd.jpg "data-size=" normal "data-rawwidth=" 772 "class=" origin_image Zh-lightbox-thumb "width=" 772 "data-original=" https://pic2.zhimg.com/d8b82e07ea21375ca6b300f9162aa95f_r.jpg " >
Builder.append ("4")
<img data-rawheight= "424" src= "https://pic1.zhimg.com/50/ Ff2ede9c6c55568d42425561f25a0fd7_hd.jpg "data-size=" normal "data-rawwidth=" 696 "class=" origin_image Zh-lightbox-thumb "width=" 696 "data-original=" https://pic1.zhimg.com/ff2ede9c6c55568d42425561f25a0fd7_r.jpg " >
Here is a diagram of the fourth example:
<img data-rawheight= "398" src= "https://pic2.zhimg.com/50/ D8b82e07ea21375ca6b300f9162aa95f_hd.jpg "data-size=" normal "data-rawwidth=" 772 "class=" origin_image Zh-lightbox-thumb "width=" 772 "data-original=" https://pic2.zhimg.com/d8b82e07ea21375ca6b300f9162aa95f_r.jpg " >
Builder = new StringBuilder ("ipad"); After
<img data-rawheight= "438" src= "https://pic1.zhimg.com/50/ 46fa5f10cc135a3ca087dae35a5211bd_hd.jpg "data-size=" normal "data-rawwidth=" 710 "class=" origin_image Zh-lightbox-thumb "width=" 710 "data-original=" https://pic1.zhimg.com/46fa5f10cc135a3ca087dae35a5211bd_r.jpg " >
January 31, 2018 add some content:
The answer is a lot of praise, although the answer was not particularly detailed, today a little more about the various types of data in memory storage.
Start with the local variable/method parameter:
Local variables and method parameters are stored in the JVM in the same way that they are stored on the stack, and the exit method is recycled as the entry method opens up. In the case of 32-bit JVMs, boolean/byte/short/char/int/float and references are allocated 4 bytes of space and Long/double allocate 8 bytes of space. For each method, the maximum amount of space is certain, which can be calculated at compile time.
We all know that there are stacks and heap in the JVM memory model, but more accurately, each thread is assigned a unique stack, and all threads share a heap. For the local variables of each method, it is absolutely impossible to be accessed by other methods, even by the same method of other threads, not to mention modifications.
When we declare an int i = 0 in a method, or object obj = null, only the stack is involved and the heap is not affected, when we new object (), a memory is opened in the heap and the object is initialized. When we assign this object to the obj variable, only the 4 bytes representing obj in the stack are changed to the address of the object.
Array type references and objects:
When we declare an array, such as int[] arr = new INT[10], because the array is also an object, arr is actually a reference, the stack occupies only 4 bytes of space, and new int[10] opens an array object in the heap, then arr points to it.
When we declare a two-dimensional array, such as int[][] arr2 = new INT[2][4],ARR2 also occupies only 4 bytes in the stack, it creates an array of length 2 in memory, a type of int[], and then arr2 points to the array. There are two references inside this array (4 bytes in size), pointing to two arrays of type int with length 4.
<img data-rawheight= "740" src= "https://pic4.zhimg.com/50/ V2-6590cb935ae8bf3b7241cb309fe041d7_hd.jpg "data-size=" normal "data-rawwidth=" 1498 "class=" origin_image Zh-lightbox-thumb "width=" 1498 "data-original=" Https://pic4.zhimg.com/v2-6590cb935ae8bf3b7241cb309fe041d7_r.jpg " >
So when we pass an array reference to a method, the elements of the array can be changed, but the array reference cannot be pointed to the new array.
You can also declare this: int[][] arr3 = new int[3][], when the memory condition is as
<img data-rawheight= "656" src= "https://pic1.zhimg.com/50/ V2-fdc86227021d56a02b559d6485983c71_hd.jpg "data-size=" normal "data-rawwidth=" 1408 "class=" Origin_image Zh-lightbox-thumb "width=" 1408 "data-original=" Https://pic1.zhimg.com/v2-fdc86227021d56a02b559d6485983c71_r.jpg " >
You can also do this arr3[0] = new int [5]; ARR3[1] = arr2[0];
<img data-rawheight= "1026" src= "https://pic3.zhimg.com/50/ V2-fdc5e737a95d625a47d66ab61e4a2f55_hd.jpg "data-size=" normal "data-rawwidth=" 1758 "class=" origin_image Zh-lightbox-thumb "width=" 1758 "data-original=" https://pic3.zhimg.com/v2-fdc5e737a95d625a47d66ab61e4a2f55_r.jpg " >
About string:
The original answer to the diagram of the string is simplified, in fact, the string object inside only need to maintain three variables, char[] chars, int startIndex, int length. Chars, in some cases, can be shared. But because string is designed to be immutable, it is also possible to consider a string object as a simplification when you think about it.
String str = new string ("Hello")
<img data-rawheight= "628" src= "https://pic1.zhimg.com/50/ V2-a143d0a3594d06f54c6853c46c429e08_hd.jpg "data-size=" normal "data-rawwidth=" 1394 "class=" origin_image Zh-lightbox-thumb "width=" 1394 "data-original=" https://pic1.zhimg.com/v2-a143d0a3594d06f54c6853c46c429e08_r.jpg " >
Of course, some JVM implementations put a string object generated by the "Hello" literal into a constant pool, and the objects in the constant pool can actually be allocated in the heap, and some implementations may be allocated in the method area, which is of course not very significant to our understanding.
Whether Java is a value pass or a reference pass