Thoughts on Java Piles and Stacks

xiaoxiao2021-04-08  6

1. Stacks and Heap are places where Java is used to store data in RAM. Unlike C , Java automatic management stacks and stacks, programmers cannot set up stacks or stacks directly.

2. The advantage of the stack is that the access speed is faster than the pile, second only to the register directly in the CPU. However, the disadvantage is that the data size in the stack must be determined, lack of flexibility. In addition, the stack data can be shared, see you 3. The strength of the heap is to dynamically allocate memory size, and the survival period does not have to tell the compiler in advance. Java's garbage collector will automatically receive these no longer used data. But the disadvantage is that the access speed is slower due to the dynamic distribution of memory during operation.

3. There are two types of data in Java.

One is a basic type (Primitive Types), with a total of Int, Short, Long, Byte, Float, Double, Boolean, Char (Note, and has a basic type of String). This type of definition is defined by the form of INT A = 3; long b = 255L, referred to as auto variables. It is worth noting that the automatic variable is a literal value, not an instance of a class, ie not a class reference, there is no class. Such as int a = 3; here A is a reference to the int type, pointing to 3 this literal value. Data of these literal values, due to size, the survival period can be known (these literal fixed definitions inside a block, the block is exited, and the field value disappears), exists in the stack for the reason for the pursuit of speed. .

In addition, the stack has a very important particularity, which is that the data in the stack can be shared. Suppose we are defined at the same time

INT A = 3;

INT b = 3;

The compiler will process int A = 3; first it will create a reference to a a variable in the stack, then find the address that there is no literal value of 3, did not find, open up a address stored 3 literal value, and then a pointing the address of 3. Then process INT b = 3; after the reference variable of the creation B is created, the b is directly directed to the address of the 3 in the stack. Thus, the case where A and B are simultaneously pointed to 3.

Special note is that the reference to this literal value is different from the reference of the class object. Assuming that the references of the two class objects simultaneously point to an object, if an object reference variable modifies the internal state of this object, then another object reference variable also reflects this change. Instead, the value of the value is modified by a reference to the literal value, and the value of another reference to this word value is also changed. As in the above example, after we define the value of A and B, let a = 4; then, B will not equal 4 or equal to 3. Inside the compiler, encounter a = 4; when it re-searches for the literal value in the stack, if not, re-open the value of the address stored 4; if there is already, directly point to this address . Therefore, the change in A value does not affect the value of B.

The other is a class of packaging data, such as Integer, String, Double, etc. to package the corresponding basic data type. All of these data exist in the stack, Java uses a new () statement to show the compiler, which is dynamically created as needed at runtime, so it is more flexible, but the disadvantage is to take up more time.

4. String is a special packaging class data. It can be created in the form of string str = new string ("abc"); can also be created in the form of string str = "abc"; as contrast, before JDK 5.0, you never have seen INTEGER I = 3; expression, because the class and literal value are universal, in addition to String. In JDK 5.0, this expression is possible! Because the compiler performs Integer i = new integer (3) conversion in the background) . The former is the creation process of the specification, that is, in Java, everything is an object, and the object is an instance of the class, all of which are created in the form of new (). Some classes in Java, such as the DateFormat class, can return a newly created class through the GetInstance () method of this class, which seems to violate this principle. actually not. This class uses a single example mode to return an instance of the class, but this instance is created in this class through new (), and GetInstance () hides this detail to the outside. Then why is in string str = "abc"; do not create an instance through new (), is it in violation of the above principles? In fact, there is no. 5. About String Str = "ABC" internal work. This statement is converted to the following steps within Java:

(1) First define an object reference variable called String class: String Str;

(2) Find the address that there is no storage value "ABC" in the stack. If not, open an address that stores a face value "ABC", then create a new String class object O, and the character of O The string value points to this address and records the object O of this reference next to this address in the stack. If there is already an address of the value "ABC", the object O is found and the address of O is returned.

(3) Point the STR to the address of the object O.

It is worth noting that the string values ​​in the general String class are all direct value. But like string str = "abc"; this occasion, its string value is saved a reference to the data in the stack!

In order to better illustrate this problem, we can verify the following code.

String str1 = "abc";

String str2 = "abc";

System.out.Println (str1 == str2); // true

Note that we don't have to str1.equals (str2) here, because this will compare whether the value of the two strings is equal. ==, according to JDK, only the true value is returned when the two references point to the same object. And what we depends here is that STR1 and STR2 point to the same object.

The results indicate that the JVM creates two references STR1 and STR2, but only one object is created, and both reference points point to this object.

Let's make further, change the above code:

String str1 = "abc";

String str2 = "abc";

Str1 = "bcd";

System.out.println (str1 "," str2); // BCD, ABC

System.out.println (str1 == str2); // false This is to say that the change in assignment has led to changes in class object reference, and STR1 points to another new object! And STR2 still points to the original object. In the above, when we change the value of STR1 to "BCD", the JVM found that the address did not store the value in the stack, opened up this address, and created a new object, and the value of its string pointed this address.

In fact, the String class is designed to become a class that cannot be changeable. If you want to change its value, you can, but JVM is running in accordance with the new value in runtime, then returns the address of this object to the original class. This creation process is fully automated, but it takes more time after all. In an environment where time requires a relatively sensitive environment, there will be a certain adverse effect.

Modify the original code:

String str1 = "abc";

String str2 = "abc";

Str1 = "bcd";

String str3 = STR1;

System.out.println (STR3); // BCD

String str4 = "bcd";

System.out.Println (str1 == str4); // true

STR3 This object is referenced directly to the object points to STR1 (note that STR3 does not create a new object). When STR1 changes its value, create a String reference STR4, and point to new objects created by modifying values ​​due to STR1. It can be found that this back STR4 has not created a new object, so that the sharing of data in the stack is again implemented.

We will then look at the following code.

String str1 = new string ("ABC");

String str2 = "abc";

System.out.println (str1 == str2); // false

Two references were created. Two objects have been created. Two references points to different objects, respectively.

String str1 = "abc";

String str2 = new string ("abc");

System.out.println (str1 == str2); // false

Two references were created. Two objects have been created. Two references points to different objects, respectively.

The above two code descriptions, as long as you use new () to create new objects, it will be created in the heap, and its string is individually saved, even if it is the same as the data in the stack, it will not share data in the stack. .

6. The value of the data type packaging class cannot be modified. Not only the value of the String class is not modified, and all data type packages cannot change their internal values.

7. Conclusions and Suggestions:

(1) When we use the format definition classes such as String Str = "ABC", we always think of it, we always think that we created the String class object STR. Worried about traps! Objects may not be created! The only thing that can be sure is that the reference to the String class is created. As for this reference to whether or not to point to a new object, must be considered in accordance with the context, unless you create a new object through the new () method. Therefore, more accurate statement is that we have created a reference variable STR to objects of the String class, which points to a String class that is "ABC". Wake-up recognition is very helpful for BUG that is difficult to discover in the exclusion program.

(2) Use string str = "abc"; can improve the running speed of the program to a certain extent, because the JVM automatically determines whether it is necessary to create a new object according to the actual situation of the data in the stack. For String Str = New String ("ABC"), the code is created in the heap, regardless of whether its string value is equal, it is necessary to create a new object, thus agggetting the burden of the program. This idea should be the idea of ​​enjoys a yuan, but the internal JDK is implemented here, which is not known. (3) When the value in the comparison is equal, use the equals () method; if the reference to the two packaging classes is tested to the same object, use ==.

(4) Due to the IMMutable nature of the String class, when String variables need to change their values ​​frequently, consider using the StringBuffer class to improve program efficiency.


New Post(0)