Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Summary of knowledge points about String source code

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly explains the "summary of knowledge points about String source code", the content of the explanation is simple and clear, easy to learn and understand, now please follow the editor's ideas slowly in depth, together to study and learn "summary of knowledge points about String source code"!

I don't know if everyone has had such an experience, that is, I inadvertently clicked in to get a karma, and then went inside to browse for a long time. That's how I got it. Today, unwittingly, ctrl+ left button, I clicked into the string source code. I happened to have nothing to do this afternoon. I just took a look inside. Unexpectedly, the next time I got over it, my colleague photographed me and asked me to go to dinner. Ha, but the advantage is. I have also sorted out some knowledge points of string class here and shared them with you. If it is not sorted out well, I hope Haihan will be able to do so.

The first official account of the article: Java Alliance of Architects, daily update of good technical articles

I. string class

The best way to understand a class is to look at the implementation source code of the class and take a look at the source code of the String class:

Public final class String implements java.io.Serializable, Comparable, CharSequence {/ * * The value is used for character storage. * / private final char value []; / * * The offset is the first index of the storage that is used. * / private final int offset; / * * The count is the number of characters in the String. * / private final int count; / * * Cache the hash code for the string * / private int hash; / / Default to 0 / * use serialVersionUID from JDK 1.0.2 for interoperability * / private static final long serialVersionUID =-6849794470754667710L;.}

The following points can be seen from the above:

1) the String class is a final class, which means that the String class cannot be inherited, and its member methods default to the final method. In Java, classes decorated by final are not allowed to be inherited, and member methods in this class default to the final method.

2) all the member attributes in the String class are listed above, from which you can see that the String class actually saves strings through the char array.

Let's move on to some method implementations of the String class:

Public String substring (int beginIndex, int endIndex) {if (beginIndex)

< 0) { throw new StringIndexOutOfBoundsException(beginIndex); } if (endIndex >

Count) {throw new StringIndexOutOfBoundsException (endIndex);} if (beginIndex > endIndex) {throw new StringIndexOutOfBoundsException (endIndex-beginIndex);} return ((beginIndex = = 0) & & (endIndex = = count)? This: new String (offset + beginIndex, endIndex-beginIndex, value);} public String concat (String str) {int otherLen = str.length (); if (otherLen = 0) {return this;} char buf [] = new char [count + otherLen]; getChars (0, count, buf, 0); str.getChars (0, otherLen, buf, count); return new String (0, count + otherLen, buf) } public String replace (char oldChar, char newChar) {if (oldChar! = newChar) {int len = count; int i =-1; char [] val = value; / * avoid getfield opcode * / int off = offset; / * avoid getfield opcode * / while (+ + I

< len) { if (val[off + i] == oldChar) { break; } } if (i < len) { char buf[] = new char[len]; for (int j = 0 ; j < i ; j++) { buf[j] = val[off+j]; } while (i < len) { char c = val[off + i]; buf[i] = (c == oldChar) ? newChar : c; i++; } return new String(0, len, buf); } } return this;} 从上面的三个方法可以看出,无论是sub操、concat还是replace操作都不是在原有的字符串上进行的,而是重新生成了一个新的字符串对象。也就是说进行这些操作后,最原始的字符串并没有被改变。 在这里要永远记住一点:"String对象一旦被创建就是固定不变的了,对String对象的任何改变都不影响到原对象,相关的任何change操作都会生成新的对象"。 二、字符串常量池 我们知道字符串的分配和其他对象分配一样,是需要消耗高昂的时间和空间的,而且字符串我们使用的非常多。JVM为了提高性能和减少内存的开销,在实例化字符串的时候进行了一些优化:使用字符串常量池。每当我们创建字符串常量时,JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么就直接返回常量池中的实例引用。如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中。由于String字符串的不可变性我们可以十分肯定常量池中一定不存在两个相同的字符串(这点对理解上面至关重要)。 Java中的常量池,实际上分为两种形态:静态常量池和运行时常量池。 所谓静态常量池,即*.class文件中的常量池,class文件中的常量池不仅仅包含字符串(数字)字面量,还包含类、方法的信息,占用class文件绝大部分空间。 而运行时常量池,则是jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在方法区中,我们常说的常量池,就是指方法区中的运行时常量池。 来看下面的程序: String a = "chenssy";String b = "chenssy"; a、b和字面上的chenssy都是指向JVM字符串常量池中的"chenssy"对象,他们指向同一个对象。 String c = new String("chenssy"); new关键字一定会产生一个对象chenssy(注意这个chenssy和上面的chenssy不同),同时这个对象是存储在堆中。所以上面应该产生了两个对象:保存在栈中的c和保存堆中chenssy。但是在Java中根本就不存在两个完全一模一样的字符串对象。故堆中的chenssy应该是引用字符串常量池中chenssy。所以c、chenssy、池chenssy的关系应该是:c--->

Chenssy--- > Pool chenssy. The whole relationship is as follows:

Through the above picture, we can clearly understand the relationship between them. So we modify the value in memory, and he changes all.

* * Summary: * * although a, b, c and chenssy are different objects, we can understand the above from the internal structure of String. String c = new String ("chenssy"); although the content of c is created in the heap, his internal value still points to the value of the chenssy of the JVM constant pool, and the argument it uses when constructing the chenssy is still the chenssy string constant.

Let's look at a few more examples:

Example 1:

/ * assign values literally * / public void test1 () {String str1= "aaa"; String str2= "aaa"; System.out.println ("= test1="); System.out.println (str1==str2); / / true can see that str1 and str2 point to the same object}

Execute the above code, and the result is: true. Analysis: when executing String str1= "aaa", JVM first goes to the string pool to look for the existence of the object "aaa". If not, it creates the object "aaa" in the string pool, and then returns the reference address of the object "aaa" in the pool to the string constant str1, so that str1 points to the string object "aaa" in the pool. If it exists, no object is created, but the address of the object "aaa" in the pool is returned and assigned to the string constant. When creating the string object str2, the object "aaa" already exists in the string pool, and the reference address of the object "aaa" is returned directly to str2, so that str2 points to the object "aaa" in the pool, that is, str1 and str2 point to the same object, so the statement System.out.println (str1 = = str2) outputs: true.

Example 2:

/ * create a new string object with the new keyword * / public void test2 () {String str3=new String ("aaa"); String str4=new String ("aaa"); System.out.println ("= test2="); System.out.println (str3==str4); / / false can see that different objects are generated by using new.

Execute the above code, and the result is: false.

Analysis: when creating a new string object with the new keyword, JVM first looks for the string object "aaa" in the string pool, and if so, it does not create the "aaa" object in the pool, but directly creates a "aaa" string object in the heap, and then returns the address of the "aaa" object in the heap to the reference str3. Str3 points to the "aaa" string object created in the heap If not, first create a "aaa" string object in the string pool, then create a "aaa" string object in the heap, and then return the address of the "aaa" string object in the heap to the str3 reference, so that str3 points to the "aaa" string object created in the heap. When executing String str4=new String ("aaa"), because the object is created with the new keyword, each time the new comes out is a new object, that is, the reference str3 and str4 point to two different objects, so the statement System.out.println (str3 = = str4) outputs: false.

Example 3:

/ * compilation time determines * / public void test3 () {String s0 = "helloworld"; String S1 = "helloworld"; String S2 = "hello" + "world"; System.out.println ("= test3="); System.out.println (s0==s1); / / true can see that S0 and S1 point to the same object System.out.println (s0==s2); / / true can see that S0 and S2 point to the same object}

Execute the above code, and the result is: true, true.

Analysis: because the "helloworld" in S0 and S1 in the example are string constants, they are determined at compile time, so s0s1 is true While "hello" and "world" are also string constants, when a string is concatenated by multiple string constants, it must also be a string constant, so S2 is also parsed to a string constant at compile time, so S2 is also a reference to "helloworld" in the constant pool. So we got s0s1==s2.

Example 4:

/ * compilation time cannot be determined * / public void test4 () {String s0 = "helloworld"; String s1=new String ("helloworld"); String S2 = "hello" + new String ("world"); System.out.println ("= test4="); System.out.println (s0==s1); / / false System.out.println (s0==s2); / / false System.out.println (s1==s2); / / false}

Execute the above code, and the result is: false, false, false.

Parsing: strings created with new String () are not constant and cannot be determined at compile time, so strings created by new String () are not put into the constant pool, they have their own address space.

S0 is also a reference to "helloworld" in the constant pool. S1 is a reference to the new object "helloworld" created at run time because it cannot be determined at compile time. S2 is also a reference to a newly created object "helloworld" because it has the second half of new String ("world").

Example 5:

/ * * continue-compilation time cannot be determined * / public void test5 () {String str1= "abc"; String str2= "def"; String str3=str1+str2; System.out.println ("= test5="); System.out.println (str3== "abcdef"); / / false}

Execute the above code, and the result is: false.

Analysis: because str3 points to the "abcdef" object in the heap, and "abcdef" is the object in the string pool, the result is false. JVM puts the String str= "abc" object in the constant pool at compile time, while String str3=str1+str2 is known at run time. The new object is also done at run time. This code creates a total of five objects, two in the string pool and three in the heap. The + operator creates two String objects in the heap with values of "abc" and "def", that is, copying the two values from the string pool, creating two objects in the heap, then creating the object str3, and then assigning the heap address of "abcdef" to str3.

Step: 1) open up a middle block in the stack to store the reference str1,str1 to point to the String constant "abc" in the pool. 2) A middle block is opened in the stack to reference str2,str2 to point to the String constant "def" in the pool. 3) open a piece in the stack to store the reference str3. 4) str1 + str2 restores a new String object "abcdef" through the toString () method of the last step of StringBuilder, so a piece of space is opened up in the heap to store the object. 5) the reference str3 points to the new String object restored in the heap (str1 + str2). 6) the object pointed to by str3 is in the heap, while the constant "abcdef" is in the pool and output is false.

Example 6:

/ * compile-time optimization * / public void test6 () {String S0 = "A1"; String S1 = "a" + 1; System.out.println ("= test6="); System.out.println ((S0 = = S1)); / / result = true String S2 = "atrue"; String S3 = "a" + "true"; System.out.println ((S2 = = S3)); / / result = true String S4 = "A3.4" String S5 = "a" + 3.4; System.out.println ((S4 = = S5)); / / result = true}

Execute the above code, and the result is: true, true, true.

Analysis: during the compilation of the program, JVM optimizes the "+" connection of the constant string to the concatenated value. For example, "a" + 1 is already A1 in class after compiler optimization. The value of its string constant is determined at compile time, so the final result of the above program is true.

/ * compilation time cannot be determined * / public void test7 () {String s0 = "ab"; String S1 = "b"; String S2 = "a" + S1; System.out.println ("= test7="); System.out.println ((S0 = = S2)); / / result = false}

Execute the above code, and the result is: false.

Analysis: JVM for string references, because there is a string reference in the "+" connection of the string, and the value of the reference cannot be determined at the compilation time of the program, that is, "a" + S1 can not be optimized by the compiler, only in the run time of the program to dynamically allocate and assign the connected new address to S2. So the result of the above program is false.

Example 8:

/ * compare the difference between "+" of string constants and "+" of string references * / public void test8 () {String test= "javalanguagespecification"; String str= "java"; String str1= "language"; String str2= "specification"; System.out.println ("= test8="); System.out.println (test= = "java" + "language" + "specification"); System.out.println (test= = str + str1 + str2);}

Execute the above code, and the result is: true, false.

Analysis: why the above results? This is because the string literal concatenation operation is performed during the compilation of the Java compiler, that is, when the compiler compiles, it directly performs the "java", "language" and "specification" literals to get a "javalanguagespecification" constant, and puts the constant directly into the string pool, which is actually an optimization, combining the three literals into one. Avoid creating redundant string objects. The "+" operation of the string reference is performed during the Java run, that is, str + str2 + str3 is calculated during the program execution, and it recreates a spliced string object in the heap memory. To sum up: the literal "+" stitching occurs during compilation, and the stitched strings are stored in the string pool, while the "+" stitching operations of string references are actually performed at runtime, and the newly created strings are stored in the heap.

For direct addition strings, it is very efficient because its value is determined at the compiler, that is, the addition of strings such as "I" + "love" + "java"; is optimized to "Ilovejava" during compilation. Indirect addition (that is, including string references) is less efficient than direct addition, because reference variables are not optimized in the compiler.

Example 9:

/ * public void test9 () {String s0 = "ab"; final String S1 = "b"; String S2 = "a" + S1; System.out.println ("= test9="); System.out.println ((S0 = = S2)); / / result = true}

Execute the above code, and the result is: true.

Analysis: the only difference from example 7 is that the S1 string is modified by final. For variables modified by final, it is parsed into a local copy of the constant value at compile time, stored in its own constant pool or embedded in its byte stream. So the effect of "a" + S1 and "a" + "b" is the same. So the result of the above program is true.

Example 10:

/ * compilation time cannot be determined * / public void test10 () {String s0 = "ab"; final String S1 = getS1 (); String S2 = "a" + S1; System.out.println ("= test10="); System.out.println ((S0 = = S2)); / / result = false} private static String getS1 () {return "b";}

Execute the above code, and the result is: false.

Analysis: although S1 is modified with final, its assignment is returned through method calls, so its value can only be determined during operation, so S0 and S2 do not point to the same object, so the result of the above program is false.

III. Summary

The 1.String class is immutable after initialization (immutable)

String uses private final char value [] to store strings, that is, after the String object is created, you can no longer modify the string contents stored in the object, which is why the String type is immutable. Programmers cannot modify existing immutable objects. We can also create immutable objects ourselves, as long as there is no way to modify the data in the interface. However, string class objects do have the ability to edit strings, such as replace (). These editing functions are achieved by creating a new object, rather than by modifying the original object. For example:

S = s.replace ("World", "Universe")

The call to s.replace () on the will create a new string "Hello Universe!" and return a reference to the object. By assigning, the reference s will point to the new string. If there are no other references to the original string "Hello World!", the original string object will be garbage collected.

two。 Reference variables and objects

The statement An aa; declares a reference variable aa of class A (we often call it a handle), while objects are typically created through new. So aa is just a reference variable, it's not an object.

3. How to create a string

There are two ways to create strings:

(1) create a string using "" quotation marks

(2) use the new keyword to create a string.

Combined with the above example, the summary is as follows:

(1) all strings created with "" quotation marks are constant, and the string will be stored in String Pool at compile time.

(2) objects created with new String ("") are stored in heap and are newly created at run time.

When new creates a string, first check to see if there is a string with the same value in the pool, if so, copy a copy to the heap and then return the address in the heap; if not in the pool, create one in the heap and then return the address in the heap (note that there is no need to copy from the heap to the pool at this time, otherwise, the string in the heap will always be a subset of the pool, resulting in a waste of pool space!

(3) if you use string concatenators that contain only constants, such as "aa" + "aa", if you create a constant, you can determine the compilation time and store it in String Pool.

(4) objects created using string concatenators that contain variables such as "aa" + S1 are created at run time and stored in heap

4. Using String does not necessarily create an object

When executing a statement containing a string in double quotes, such as String a = "123", JVM will first look in the constant pool and return a reference to this instance in the constant pool if any, otherwise create a new instance and place it in the constant pool. So when we define an object using a format such as String str = "abc";, we always take it for granted that we have created the object str of the String class. * * worry about traps! The object may not have been created! It may just point to an object that has been previously created. * * it is only through the new () method that a new object is created each time.

5. With new String, be sure to create an object

When executing String a = new String, first take the constant pool route to get a reference to an instance, then create a new String instance on the heap, assign a value to the value property using the following constructor, and then assign the instance reference to a:

Public String (String original) {int size = original.count; char [] originalValue = original.value; char [] v; if (originalValue.length > size) {/ / The array representing the String is bigger than the new / / String itself. Perhaps this constructor is being called / / in order to trim the baggage, so make a copy of the array. Int off = original.offset; v = Arrays.copyOfRange (originalValue, off, off+size);} else {/ / The array representing the String is the same / / size as the String, so no point in making a copy. V = originalValue;} this.offset = 0; this.count = size; this.value = v;}

We can see that although a newly created instance of String is created, value is equal to the value of the instance in the constant pool, that is, there is no new a new character array to store "123".

6. About String.intern ()

The * * intern method uses: * * an initially empty string pool maintained by the class String alone. When the intern method is called, if the pool already contains a string equal to this String object (determined by the equals (oject) method), the string in the pool is returned. Otherwise, add the String object to the pool and return a reference to the String object.

It follows the following rule: for any two strings s and t, if and only if s.equals (t) is true, s.intern () = = t.intern () because true.

String.intern (): a constant pool that exists in a .class file is loaded by jvm at run time and can be expanded. The intern () method of String is a method to extend the constant pool; when a String instance str calls the intern () method, java looks for a string constant of the same unicode in the constant pool, and if so, returns its reference, and if not, adds a string with unicode equal to str in the constant pool and returns its reference.

/ * * about String.intern () * / public void test11 () {String s0 = "kvill"; String S1 = new String ("kvill"); String S2 = new String ("kvill"); System.out.println ("= test11="); System.out.println (S0 = = S1); / / false System.out.println ("*"); s1.intern () / although s1.intern () is executed, its return value is not assigned to S1 S2 = s2.intern (); / / assign the reference to "kvill" in the constant pool to S2 System.out.println (S0 = = S1); / / flase System.out.println (S0 = = s1.intern ()); / / true// indicates that s1.intern () returns the reference System.out.println (S0 = = S2) to "kvill" in the constant pool; / / true}

Running results: false, false, true, true.

7. About equals and = =

(1) for = =, if it acts on a variable of the basic data type (byte,short,char,int,long,float,double,boolean), it directly compares whether its stored "value" is equal; if it acts on a variable of a reference type (String), it compares the address of the object it points to (that is, whether it points to the same object).

(2) the equals method is a method in the base class Object, so it exists for all classes that inherit from Object. In the Object class, the equals method is used to compare whether references to two objects are equal, that is, whether they point to the same object.

(3) for equals methods, note that equals methods cannot act on variables of basic data types. If the equals method is not overridden, the address of the object pointed to by the variable of the reference type is compared, while the String class overrides the equals method to compare whether the string stored by the pointed string object is equal. Other classes, such as Double,Date,Integer, override the equals method to compare whether the content stored in the pointing object is equal.

/ * * about equals and = = / public void test12 () {String S1 = "hello"; String S2 = "hello"; String s3=new String ("hello"); System.out.println ("= test12="); System.out.println (S1 = = S2) / / true, indicating that S1 and S2 point to the same object, and they both point to the "hello" object / / flase in the constant pool, indicating that S1 and S3 have different addresses, that is, they point to different objects, S1 points to the address in the constant pool, and S3 points to the address System.out.println (S1 = = S3) in the heap; System.out.println (s1.equals (S3)) / / true, indicating that S1 and S3 point to objects with the same content}

8.String related +:

The + in String is often used for string concatenation. Look at the following simple example:

/ * * String related + * / public void test13 () {String a = "aa"; String b = "bb"; String c = "xx" + "yy" + a + "zz" + "mm" + b; System.out.println ("= test13="); System.out.println (c);}

After compiling and running, the main bytecode section is as follows:

Public static main ([Ljava/lang/String;) V L0 LINENUMBER 5 L0 LDC "aa" ASTORE 1 L1 LINENUMBER 6 L1 LDC "bb" ASTORE 2 L2 LINENUMBER 7 L2 NEW java/lang/StringBuilder DUP LDC "xxyy" INVOKESPECIAL java/lang/StringBuilder. (Ljava/lang/String;) V ALOAD 1 INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;) Ljava/lang/StringBuilder; LDC "zz" INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;) Ljava/lang/StringBuilder; LDC "mm" INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;) Ljava/lang/StringBuilder; ALOAD 2 INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;) Ljava/lang/StringBuilder INVOKEVIRTUAL java/lang/StringBuilder.toString () Ljava/lang/String; ASTORE 3 L3 LINENUMBER 8 L3 GETSTATIC java/lang/System.out: Ljava/io/PrintStream; ALOAD 3 INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;) V L4 LINENUMBER 9 L4 RETURN L5 LOCALVARIABLE args [Ljava/lang/String; L0 L5 LOCALVARIABLE a Ljava/lang/String; L1 L5 1 LOCALVARIABLE b Ljava/lang/String; L2 L5 2 LOCALVARIABLE c Ljava/lang/String L3 L5 3 MAXSTACK = 3 MAXLOCALS = 4}

Obviously, through bytecode, we can draw the following conclusions: (1) when string concatenation is carried out with + string concatenator in string, if the concatenation operation is string constant at the beginning, the string constants will be directly connected as much as possible after compilation to form new string constants to participate in subsequent connections (which can also be easily seen through the decompiler tool jd-gui).

(2)。 The next string concatenation is carried out from left to right. For different strings, first create a StringBuilder object with the leftmost string as a parameter, then append the right in turn, and finally convert the StringBuilder object into a String object through the toString () method (note: multiple string constants in the middle are not automatically concatenated).

That is to say, String c = "xx" + "yy" + a + "zz" + "mm" + b; in essence, the implementation process is: String c = new StringBuilder ("xxyy") .append (a) .append ("zz"). Append ("mm") .append (b). ToString ()

The conclusion is that when you use + to concatenate multiple strings, you actually produce a StringBuilder object and a String object.

The immutability of 9.String results in the cost of using the + sign for string variables:

String s = "a" + "b" + "c"; String S1 = "a"; String S2 = "b"; String S3 = "c"; String S4 = S1 + S2 + S3

Analysis: the creation of the variable s is equivalent to String s = "abc"; from the above example, the compiler is optimized and only one object is created. From the above example, we can also know that S4 cannot be optimized at compile time, and its object creation is equivalent to:

StringBuilder temp = new StringBuilder (); temp.append (a) .append (b) .append (c); String s = temp.toString ()

From the above analysis results, it is not difficult to infer that String uses the join operator (+) to analyze the reasons for its inefficiency, such as this code:

Public class Test {public static void main (String args []) {String s = null; for (int I = 0; I)

< 100; i++) { s += "a"; } }} 每做一次 + 就产生个StringBuilder对象,然后append后就扔掉。下次循环再到达时重新产生个StringBuilder对象,然后 append 字符串,如此循环直至结束。 如果我们直接采用 StringBuilder 对象进行 append 的话,我们可以节省 N - 1 次创建和销毁对象的时间。所以对于在循环中要进行字符串连接的应用,一般都是用StringBuffer或StringBulider对象来进行append操作。 10.String、StringBuffer、StringBuilder的区别 (1)可变与不可变:String是不可变字符串对象,StringBuilder和StringBuffer是可变字符串对象(其内部的字符数组长度可变)。 (2)是否多线程安全:String中的对象是不可变的,也就可以理解为常量,显然线程安全。StringBuffer 与 StringBuilder 中的方法和功能完全是等价的,只是StringBuffer 中的方法大都采用了synchronized 关键字进行修饰,因此是线程安全的,而 StringBuilder 没有这个修饰,可以被认为是非线程安全的。 (3)String、StringBuilder、StringBuffer三者的执行效率: StringBuilder >

StringBuffer > String of course this is relative, not necessarily in all cases. For example, String str = "hello" + "world" is more efficient than StringBuilder st = new StringBuilder (). Append ("hello"). Append ("world"). Therefore, these three classes have their own advantages and disadvantages, and should be chosen according to different situations: when string addition operations or changes are less, it is recommended to use the form of String str= "hello"; when there are more string addition operations, it is recommended to use StringBuilder, if multithreading is used, then use StringBuffer.

The usage and understanding of final in 11.String

Final StringBuffer a = new StringBuffer; final StringBuffer b = new StringBuffer / this sentence is compiled without passing final StringBuffer a = new StringBuffer; a.append; / / compiled

It can be seen that * * final is only valid for the "value" of the reference (that is, the memory address). It forces the reference to point only to the object that was originally pointed to, and changing its direction will lead to compile-time errors. * * final is not responsible for changes in the objects it points to.

twelve。 How many objects have been created about String str = new String ("abc")?

This question is mentioned in many books, such as the interview Book for Java programmers, including the written interview questions of many large domestic companies, and most of the online circulation and some interview books say that there are two subjects, which is one-sided.

First of all, you have to figure out the meaning of creating an object. When was it created? Will this code create 2 objects during run time? There is no doubt that it is impossible to decompile with javap-c to get the bytecode content of JVM execution:

Obviously, new is called only once, which means that only one object is created. And the confusing thing about this title is that this code does create only one object at run time, that is, a "abc" object on the heap. And why is everyone talking about two objects? it is necessary to clarify the concept that there is a difference between the execution of this code and the loading process of the class. During class loading, it is true that a "abc" object is created in the runtime constant pool, while only one String object is created during code execution. So, how many String objects are involved in String str = new String ("abc") instead? The reasonable explanation is two. Personally, if you encounter this question during the interview, you can ask the interviewer "how many objects have been created or how many objects are involved in the execution of this code?" and then answer according to the specific.

13. Advantages and disadvantages of string pool: the advantage of string pool is that it avoids the creation of strings with the same content, saves memory, saves the time of creating the same string, and improves performance; on the other hand, the disadvantage of string pool is that it sacrifices the time required for JVM to traverse objects in constant pool, but its time cost is relatively low.

IV. Comprehensive examples

Package com.spring.test;public class StringTest {public static void main (String [] args) {/ * scenario 1: there is a string pool in the string pool * JAVA virtual machine (JVM) that holds many String objects; * and can be shared, so it improves efficiency. * because the String class is final, its value cannot be changed once created. * the string pool is maintained by the String class, and we can call the intern () method to access the string pool. * / String S1 = "abc"; / / ↑ creates an object String S2 = "abc" in the string pool; / / the ↑ string pool already has an object "abc" (shared), so create 0 objects and accumulate one object System.out.println ("s1==s2:" + (s1==s2)) / / ↑ true points to the same object, System.out.println ("s1.equals (S2):" + (s1.equals (S2) / / ↑ true equals / / ↑-over / * scenario 2: about new String (") * / String S3 = new String ("abc") / / ↑ creates two objects, one in the string pool and one in the heap area / / ↑ also has an object reference S3 stored in the stack String S4 = new String ("abc"); / / the "abc" object already exists in the ↑ string pool, so only one object System.out.println ("s3==s4:" + (s3==s4)) is created in the heap; / / ↑ false S3 and S4 stack areas have different addresses and point to different addresses of the heap area System.out.println ("s3.equals (S4):" + (s3.equals (S4); / / ↑ true S3 and S4 have the same values System.out.println ("s1==s3:" + (s1==s3)) / / ↑ false is stored in different regions, including one stack area and one stack area System.out.println ("s1.equals (S3):" + (s1.equals (S3) / / ↑ true values are the same / / ↑-over / * * scenario 3: * because the value of the constant is determined (optimized) at compile time. * here, "ab" and "cd" are constants, so the value of the variable str3 can be determined at compile time. * the compiled effect of this line of code is equivalent to: String str3 = "abcd"; * / String str1 = "ab" + "cd"; / / 1 object String str11 = "abcd"; System.out.println ("str1 = str11:" + (str1 = = str11)) / / ↑-over / * * scenario 4: * the local variable str2,str3 stores the address of two detention string objects (intern string objects). * * third line of code principle (str2+str3): * Runtime JVM first creates a StringBuilder class in the heap, * initializes it with the detention string object pointed to by str2, * then calls the append method to merge the detention string pointed to by str3, and * then calls the toString () method of StringBuilder to create a String object in the heap. * finally, the heap address of the newly generated String object is stored in the local variable str3. * * str5 stores the address of the detained string object corresponding to "abcd" in the string pool. * the str4 address is certainly different from the str5 address. * * there are actually five string objects in memory: * three detention string objects, one String object and one StringBuilder object. * / String str2 = "ab"; / / 1 object String str3 = "cd"; / / 1 object String str4= str2+str3; String str5 = "abcd"; System.out.println ("str4= str5:" + (str4==str5)) / / false / / ↑-over / * scenario 5: * the JAVA compiler optimizes string + primitive types / constants as constant expressions. * the addition of two string at runtime produces a new object, which is stored in the heap (heap) * / String str6 = "b"; String str7 = "a" + str6; String str67 = "ab"; System.out.println ("str7 = str67:" + (str7 = = str67)); / / ↑ str6 is a variable and will only be parsed at run time. Final String str8 = "b"; String str9 = "a" + str8; String str89 = "ab"; System.out.println ("str9 = str89:" + (str9 = = str89)) / / ↑ str8 is a constant variable, and the compilation time will be optimized / / ↑-over}}

Running result:

S1 = = S2: true s1.equals (S2): true S3 = = S4: false s3.equals (S4): true S1 = = S3: false s1.equals (S3): true str1 = str11: true str4 = str5: false str7 = str67: false str9 = str89: true

Thank you for your reading, the above is the "summary of String source knowledge points" of the content, after the study of this article, I believe you on the String source code knowledge summary of this issue has a deeper understanding, the specific use of the need for you to practice and verify. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

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.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report