In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces "analyzing the storage area and immutability of String in JDK". In daily operation, I believe that many people have doubts in analyzing the storage area and immutability of String in JDK. Xiaobian consulted all kinds of data and sorted out simple and easy-to-use methods of operation. I hope it will be helpful to answer the doubt of "analyzing the storage area and immutability of String in JDK". Next, please follow the editor to study!
1. Data storage area
String is a special class that can be defined by literal constants in addition to new. To figure out the difference between the two, we first need to understand the JVM runtime datastore, which is clearly described in a diagram:
Non-shared datastore
Non-shared datastores are created when the thread starts, including:
Program counter (program counter register) controls the execution of threads
The stack (JVM Stack, Native Method Stack) stores method calls, references to objects, and so on.
Shared datastore
The store is shared by all threads and can be divided into:
The Heap stores all Java objects and automatically allocates memory in the heap when the new object is executed.
The method area (Method Area) stores constant pools (run-time constant pool), data for fields and methods, and code for methods and constructors.
two。 Two kinds of instantiation
Instantiate the String object:
Public class StringLiterals {public static void main (String [] args) {String one = "Test"; String two = "Test"; String three = "T" + "e" + "s" + "t"; String four = new String ("Test");}}
Javap-c StringLiterals is decompiled to generate bytecode. We select the following parts of interest:
Public static void main (java.lang.String []) Code: 0: ldc # 2 / / String Test 2: astore_1 3: ldc # 2 / / String Test 5: astore_2 6: ldc # 2 / / String Test 8: astore_3 9: new # 3 / / class java/lang/String 12: dup 13: ldc # 2 / / String Test 15: invokespecial # 4 / / Method java/lang/String. "(Ljava/lang/String ) V 18: astore 4 20: return}
Ldc # 2 means taking the constant of # 2 from the constant pool into the stack, and astore_1 means that the reference will be stored in the local variable 1. Therefore, we can see that objects one, two, and three all point to the literal constant "Test" in the constant pool; object four is a new object that new in the heap, as shown in the following figure:
The summary is as follows:
When instantiated with literal constants, String objects are stored in the constant pool
When instantiated with new, String objects are stored in the heap
The operator = = compares references to objects, or false when they point to different objects. As a result, the code at the beginning will show that the String object created through new is different.
3. Immutable String
String source code
String class of JDK7:
Public final class String implements java.io.Serializable, Comparable, CharSequence {/ * * The value is used for character storage. * / private final char value []; / * * Cache the hash code for the string * / private int hash; / / Default to 0}
The String class is declared as final and cannot be inherited, and all methods are implicitly specified as final because they cannot be overridden. The field char value [] represents the string corresponding to the String class, which is declared as private final; and cannot be modified after initialization. Constructor of the commonly used new instantiation object String S1 = new String ("abcd");:
Public String (String original) {this.value = original.value; this.hash = original.hash;}
Just pass the field values of value and hash.
Immutability
The so-called immutability means that classes cannot be modified through the usual API. To better understand immutability, let's first look at a piece of code from "Thinking in Java":
/: operators/Assignment.java// Assignment with objects is a bit tricky.import static net.mindview.util.Print.*;class Tank {int level;} public class Assignment {public static void main (String [] args) {Tank T1 = new Tank (); Tank T2 = new Tank (); t1.level = 9; t2.level = 47; print ("1: t1.level:" + t1.level + ", t2.level:" + t2.level) T1 = T2; print ("2: t1.level:" + t1.level + ", t2.level:" + t2.level); t1.level = 27; print ("3: t1.level:" + t1.level + ", t2.level:" + t2.level) } / * Output:1: t1.level: 9, t2.level: 472,472: t1.level: 47, t2.level: 473: t1.level: 27, t2.level: 27.
In the above code, in the assignment operation T1 = T2; after that, T1 and T2 contain the same reference, pointing to the same object. Therefore, the modification of the T1 object directly affects the field change of the T2 object. Obviously, the Tank class is mutable.
Maybe someone would say s = s.concat ("ef"); didn't you modify the object s? In fact, if we look at the implementation of concat, we will find that it returns a new String object (return new String (buf, true);); it only changes the object pointed to by the S1 reference, as shown in the following figure:
4. Reflection
The value field of String is final. Can it be modified in some way? The answer is reflex. There is a code on stackoverflow that modifies the value field:
String S1 = "Hello World"; String S2 = "Hello World"; String S2 = s1.substring (6); System.out.println (S1); / / Hello World System.out.println (S2); / / Hello World System.out.println (S3); / / World Field field = String.class.getDeclaredField ("value"); field.setAccessible (true); char [] value = (char []) field.get (S1); value [6] = 'Jacks; value [7] =' a' Value [8] = 'vested; value [9] =' await; value [10] ='!'; System.out.println (S1); / / Hello Java! System.out.println (S2); / / Hello Java! System.out.println (S3); / / World
In the above code, why is the value of object S2 also modified, while the value of object S3 is not? According to the previous introduction, S1 and S2 point to the same object; so when S1 is modified, S2 is modified accordingly. As for S3 objects, why not? Let's look at the implementation of substring ():
Public String substring (int beginIndex) {if (beginIndex < 0) {throw new StringIndexOutOfBoundsException (beginIndex);} int subLen = value.length-beginIndex; if (subLen < 0) {throw new StringIndexOutOfBoundsException (subLen);} return (beginIndex = = 0)? This: new String (value, beginIndex, subLen);}
When beginIndex is not 0, the String object of new is returned; when beginIndex is 0, the original object itself is returned. If you change String S3 = s1.substring (6); to String S3 = s1.substring (0);, then object S3 will also be modified.
If you look closely at java.lang.String.java, you can see that when you need to change the contents of a string, the method of the String class returns the new String object; if not, the method of the String class returns the original object reference. This saves storage space and additional overhead.
At this point, the study on "analyzing the storage area and immutability of String in JDK" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.