Deep understanding of Java string and intern by anti-compilation

Source: Internet
Author: User

First, string problems

String in our usual coding work in fact, and it is relatively simple to use, so very few people to do special in-depth research. In the interview or written test, often involves more in-depth and difficult problems. I also occasionally ask the applicant related questions in the recruitment, not to say that must be answered in particular correct and in-depth, usually ask these questions for two purposes, the first is to examine the basic knowledge of JAVA, the second is to examine the applicant's attitude towards technology.

Let's see what the following program will output. If you can answer each question correctly and know the reason, then this article is of little significance to you. If the answer is not correct or is not clear about its principle, then take a closer look at the following analysis, this article should be able to help you clearly understand the results of each program and the underlying reasons for the output of the results.

Code Snippet One:

?
1234567891011 package com.paddx.test.string;public class StringTest {    public static void main(String[] args) {        String str1 = "string";        String str2 = new String("string");        String str3 = str2.intern();        System.out.println(str1==str2);//#1        System.out.println(str1==str3);//#2    }}

Code Snippet Two:

?
1 packagecom.paddx.test.string;
?
1234567891011121314151617 public class StringTest01 {    public static void main(String[] args) {        String baseStr = "baseStr";        final String baseFinalStr = "baseStr";        String str1 = "baseStr01";        String str2 = "baseStr"+"01";        String str3 = baseStr + "01";        String str4 = baseFinalStr+"01";        String str5 = new String("baseStr01").intern();         System.out.println(str1 == str2);//#3        System.out.println(str1 == str3);//#4        System.out.println(str1 == str4);//#5        System.out.println(str1 == str5);//#6    }}

Code snippet three (1):

?
12345678910 package com.paddx.test.string;<br>  public class InternTest {    public static void main(String[] args) {        String str2 = new String("str")+new String("01");        str2.intern();        String str1 = "str01";        System.out.println(str2==str1);//#7    }}

Code snippet three (2):

?
12345678910 package com.paddx.test.string;public class InternTest01 {    public static void main(String[] args) {        String str1 = "str01";        String str2 = new String("str")+new String("01");        str2.intern();        System.out.println(str2 == str1);//#8    }}

To facilitate the description, my output of the above code is #8进行了编码 by #1~, and the Blue font section below is the result.

Second, string in-depth analysis

  1, code segment one analysis

  A string is not a primitive type, but it can be directly assigned to a literal, like a basic type, or a string object can be generated from new. However , there is an essential difference between generating a string in the way of literal assignment and new:

When a string is created by literal assignment, it is preferred to find in the constant pool whether the same string already exists, and if it already exists, the reference in the stack points directly to that string, and if it does not exist, a string is generated in the constant pool, and the reference in the stack is pointed to the string. When you create a string by using new, the object that generates a string directly in the heap (note, after JDK 7, the HotSpot has moved the constant pool from the permanent generation to the heap.) For more information, refer to the JDK8 memory model-Vanishing PermGen article), and the reference in the stack points to the object. For a string object in a heap, you can add a string to the constant pool by using the Intern () method, and return a reference to the constant.

Now we should be able to understand the results of code snippet one:

The result #1: because str1 points to constants in a string, STR2 is the object generated in the heap, so str1==str2 returns FALSE.

The result #2: STR2 calls the Intern method and copies the str2 medium value ("string") into the constant pool, but the string is already present in the constant pool (that is, the string that the str1 points to), so the reference to the string is returned directly, so STR1==STR2 returns True.

The result of the following code that runs code snippet one:

2, Code section two analysis

For the result of code snippet two, it is easier to understand the Stringtest01.class file by deserializing it:

Constant pool content (partial):

Execution instruction (partial, second column #+ ordinal corresponds to an item in a constant pool):

Before explaining the above implementation process, understand the two instructions:

Ldc:push item from Run-time constant pool, loads a reference from the specified item to the stack from the constant pool.

Astore_<n>:store reference into local variable, assigns a reference to nth local variable.

Now we begin to explain the execution of code snippet two:

0:LDC #2: Loads the second item in the constant pool ("basestr") into the stack.

2:astore_1: Assigns a reference in 1 to the first local variable, that is, string basestr = "Basestr";

3:LDC #2: Loads the second item in the constant pool ("basestr") into the stack.

5:astore_2: Assigns a reference in 3 to the second local variable, which is the final String basefinalstr= "Basestr";

6:LDC #3: Loads the third item in the Constant pool ("BaseStr01") into the stack.

8:astore_3: Assigns a reference in 6 to the third local variable, which is the string str1= "BaseStr01";

9:LDC #3: Loads the third item in the Constant pool ("BaseStr01") into the stack.

11:astore 4: Assigns a reference in 9 to the fourth local variable: string str2= "BaseStr01";

The result #3:str1==str2 will definitely return true because both str1 and str2 point to the same reference address in the constant pool. So in fact, after Java 1.6, the "+" operation of the Constant string, the compilation phase is directly joined to become a string.

13:new #4: Generates an instance of StringBuilder.

16:dup: Copy 13 of the generated object's reference and press it into the stack.

17:invokespecial #5: Calls the fifth item in the constant pool, which is the Stringbuilder.<init> method.

The purpose of the above three directives is to generate a StringBuilder object.

20:aload_1: Loads the value of the first parameter, which is "Basestr"

21:invokevirtual #6: Invokes the Append method of the StringBuilder object.

24:LDC #7: Loads the seventh item in the constant pool ("01") into the stack.

26:invokevirtual #6: Call the Stringbuilder.append method.

29:invokevirtual #8: Call the Stringbuilder.tostring method.

32:astore 5: The assignment of the result reference in 29 to the fifth local variable, that is, the assignment of the variable STR3.

The result #4: Because STR3 is actually a result of stringbuilder.append (), it is not equal to STR1 and the result returns false.

34:LDC #3: Loads the third item in the Constant pool ("BaseStr01") into the stack.

36:astore 6: Assigns a reference in 34 to the sixth local variable, i.e. str4= "BaseStr01";

The result #5: Str1==str4 returns True because Str1 and STR4 are pointing to the third item in the constant pool. Here we can also find a phenomenon, for the final field, the compilation period is directly replaced by a constant, and for non-final fields are assigned at run time.

38:new #9: Creating a String Object

41:dup: Copy the reference and press it as a stack.

42:LDC #3: Loads the third item in the Constant pool ("BaseStr01") into the stack.

44:invokespecial #10: Call string. " <init> "method, and pass the reference in 42 steps as a parameter to the method.

47:invokevirtual #11: Call the String.intern method.

The corresponding source code from 38 to 41 is the new String ("BaseStr01"). Intern ().

50:astore 7: Assigns the result of the 47-step return to the variable 7, which is where STR5 points to baseStr01 in the constant pool.

The result #6: Str1==str5 returns True because both STR5 and str1 all point to the same string in the constant pool.

Run code snippet two and the output is as follows:

3, the code snippet three analysis:

For code snippet Three, the results run differently in JDK 1.6 and JDK 1.7. Let's take a look at the results of the operation before we explain why:

Run Results under JDK 1.6:

Run results under JDK 1.7:

Based on the analysis of snippet one, the results of JDK 1.6 should be very simple, because str2 and str1 are meant to point to different locations and should return false.

The strange problem is that after JDK 1.7, it returns true for the first case, but the result returned by a reversed position becomes false. This reason is mainly from JDK 1.7, HotSpot will be the constant pool from the permanent generation moved to the meta-space, because of this, JDK 1.7 after the intern method in the implementation of a relatively large change, JDK 1.7, the Intern method will be first to query the constant pool whether there is already exist, If present, returns a reference in a constant pool, unlike before, except that if the corresponding string is not found in the constant pool, the string is no longer copied to the constant pool, but only a reference to the original string is generated in the constant pool. So:

The result #7: In the first case, because there is no string "Str01" in the constant pool, a reference to "Str01" in the heap is generated in the constant pool, and when the literal assignment is made, the constant pool already exists, so the reference is returned directly, So str1 and str2 both point to the string in the heap and return true.

The result #8: After the position is swapped, because the constant pool does not exist in the literal assignment (String str1 = "Str01"), so str1 points to the position in the constant pool, and str2 points to the object in the heap, and when the Intern method is It has no effect on str1 and str2, so return false.

Three, common face question answer

With an understanding of the above knowledge, we can now look at the common interview or written questions is very simple:

q:string s = new string ("XYZ"), creating several string Object?

A: Two, "XYZ" in a constant pool and objects in the heap.

Q: The output of the following programs:

String S1 = "abc";
String s2 = "abc";
System.out.println (S1 = = s2);

A:true, all points to the object in the constant pool.

Q: The output of the following programs:

string S1 = new String ("abc");
String s2 = new String ("abc");
System.out.println (S1 = = s2);

A:false, two references point to a different object in the heap.

Q: The output of the following programs:

String S1 = "abc";
String s2 = "a";
String s3 = "BC";
String S4 = s2 + s3;
System.out.println (S1 = = S4);

A:false, because S2+S3 is actually done using Stringbuilder.append, a different object is generated.

Q: The output of the following programs:

String S1 = "abc";
Final String s2 = "a";
Final String s3 = "BC";
String S4 = s2 + s3;
System.out.println (S1 = = S4);

A:true, because the final variable is directly replaced with the corresponding value after compilation, so it is actually equal to s4= "a" + "BC", and in this case, the compiler will be merged directly into S4= "ABC", so the final s1==s4.

Q: The output of the following programs:

string s = new String ("abc");
String S1 = "abc";
String s2 = new String ("abc");

System.out.println (s = = S1.intern ());
System.out.println (s = = S2.intern ());
System.out.println (S1 = = S2.intern ());

A:false,false,true, refer to the second part for specific reasons.

Deep understanding of Java String and Intern (RPM) by anti-compilation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.