[Java] 5 tricky String interview questions

Insert picture description here

1 Overview

Reprinted: http://www.javastack.cn/article/2020/five-hard-string-questions/

This article will take a look at five interview questions about the Java String class. These five questions, I have personally experienced several questions during the interview process. This article will take you to understand why the answers to these questions are like this.

1. Determine whether st1 and st2 defined as String type are equal, and why

package string;

public class Demo2_String {
    
    

  public static void main(String[] args) {
    
    
    String st1 = "abc";
    String st2 = "abc";
    System.out.println(st1 == st2);
    System.out.println(st1.equals(st2));
  }

}

Output result:

The first line: true

Second line: true

analysis:

Look at the first print statement 在Java中==这个符号是比较运算符,它可以基本数据类型和引用数据类型是否相等,如果是基本数据类型,==比较的是值是否相等,如果是引用数据类型,==比较的是两个对象的内存地址是否相等.

The string does not belong to the basic data types in 8, and the string object belongs to the reference data type. In the above, "abc" is assigned to the two string objects st1 and st2 at the same time, and they all point to the same address, so the first one is printed The == comparison output in the statement is true

Then we look at the comparison of equals in the second print statement. We know that equals is a method of the parent class of Object, and the equals method is overridden in the String class.

Find the equals method under the String class in the JDK API 1.6 document, click to see the sentence "Compare this string with the specified object. If and only if the parameter is not null, and it is the same as the object The result is true when the string object of the character sequence is the same.” Pay attention to this same character sequence. The comparison of two arrays, lists, and dictionaries introduced later is the logic to write code to achieve.

Since the values ​​of st1 and st2 are both "abc", they both point to the same object, and the current character sequence is the same, so the second line print result is also true.

Let's draw a memory graph to represent the above code, which looks more convincing.

Insert picture description here

The memory process is roughly as follows:

1) Run first to compile, then the current class Demo2_String.class file is loaded into the method area of ​​the memory

2) The second step, the main method is pushed into the stack memory

3) The constant pool creates an "abc" object and generates a memory address

4) Then assign the "abc" memory address to the member variable st1 in the main method. At this time, st1 points to "abc" in the constant pool based on the memory address.

5) As mentioned in the previous article, the constant pool has this feature. If it is found to already exist, it will not create a duplicate object

6) Run to the code Stringst2 = "abc", because the constant pool has "abc", it will not be created again, and the memory address of "abc" is directly assigned to st2

7) Finally, both st1 and st2 point to the same address in memory, so the two are exactly the same.

2. The following sentence creates several objects in memory

String st1 = new String(“abc”);

The answer is: create two objects in memory, one in the heap memory and one in the constant pool. The heap memory object is a copy of the constant pool object. In addition, pay attention to the WeChat public account: Java technology stack, and reply in the background: Interview, I can get the N latest Java interview questions compiled by me, all of which are dry goods.

analysis:

Let's directly come to a memory map below.
Insert picture description here

When we see the keyword new, we must think that the new objects are stored in the heap memory. Then we explain why objects in the heap are copies of objects in the constant pool.

"Abc" is a string, and a string is a constant, so it should be created in the constant pool, so the first object created is "abc" in the constant pool.

Why is the second object a copy of a copy in the heap memory? You need to find the annotation of the String (String original) construction method in JDK API 1.6: Initialize a newly created String object to make it the same as the parameter The sequence of characters; in other words, the newly created string is a copy of the parameter string.

So, the answer comes out, two objects.

3. Determine whether st1 and st2 defined as String type below are equal

package string;
public class Demo2_String {
    
    
   public static void main(String[] args) {
    
    
     String st1 = new String("abc");
     String st2 = "abc";
     System.out.println(st1 == st2);
     System.out.println(st1.equals(st2));
   }
}

Answer: false and true

Because of the experience and theory of memory analysis mentioned in the previous two courses, I can quickly get the answer above.

==比较的st1和st2对象的内存地址,由于st1指向的是堆内存的地址,st2看到“abc”已经在常量池存在,就不会再新建,所以st2指向了常量池的内存地址,所以==判断结果输出false,The two are not equal.

The second equals comparison, the comparison is whether the two string sequences are equal, because there is only one "abc", they are completely equal.

The memory diagram is as follows

Insert picture description here

4. Determine whether st1 and st2 defined as String type below are equal

package string;

public class Demo2_String {
    
    

   public static void main(String[] args) {
    
    
     String st1 = "a" + "b" + "c";
     String st2 = "abc";
     System.out.println(st1 == st2);
     System.out.println(st1.equals(st2));
   }
}

The answer is: true and true

analysis:

The three "a", "b", and "c" are originally string constants. After the + sign is spliced, they become "abc". "abc" itself is a string constant (there is a constant optimization mechanism in Java), so the constant Chi Lima will create a string constant object of "abc", in the process of st2="abc", at this time, "abc" exists in the constant pool, so it will not be created. Therefore, regardless of whether the memory address is compared or the string sequence is compared, it is equal.

5. Determine whether the following st2 and st3 are equal

package string;

public class Demo2_String {
    
    

   public static void main(String[] args) {
    
    
     String st1 = "ab";
     String st2 = "abc";
     String st3 = st1 + "c";
     System.out.println(st2 == st3);
     System.out.println(st2.equals(st3));
   }
}

Answer: false and true

analysis:

The first answer above is false, the second is true, and the second is true. We understand very well, because the comparison one is "abc" and the other is the spliced ​​"abc", so the equals comparison, this is the output true, we understand very well.

So why the first judgment is false, we are very confused. Similarly, below we use API annotations and memory diagrams to explain why this is not equal.

First, open the introduction of String in JDK API 1.6 and find the sentence in the picture below.
Insert picture description here

The key point is the sentence in the red circle. We know that any data and string are subjected to the plus (+) operation, and the final result is a spliced ​​new string. What exactly did the + operation do? Recommend to take a look. Pay attention to the WeChat public account: Java technology stack, reply in the background: java, you can get the N latest Java tutorials I have compiled, all of which are dry goods.

The above comment shows that the principle of this splicing is realized by the StringBuilder or StringBuffer class and the append method inside, and then call toString() to convert the spliced ​​object into a string object, and finally assign the address of the string object to a variable.

Combining this understanding, let's draw a memory diagram to analyze.

Insert picture description here

Approximate memory process

1) The constant pool creates an "ab" object and assigns it to st1, so st1 points to "ab"

2) The constant pool creates an "abc" object and assigns it to st2, so st2 points to "abc"

3) Because of the + splicing method here, the third step is to use the append method of the StringBuffer class to get "abc". At this time, the memory 0x0011 represents a StringBuffer object, and note that it is not a String object.

4) The toString method of Object is called to replace the StringBuffer object with a String object.

5) Assign the String object (0x0022) to st3

Therefore, the == judgment result of st3 and st2 is not equal, because the memory addresses of the two objects are different.

to sum up:

The interview questions for this article are completely required to master some of the annotations and principles in the JDK API, as well as memory map analysis, to get the correct results. I admit that drawing the memory map allows me to understand why the answer is so.

After drawing the memory map and get the answer, you will indeed find it very interesting, and finally you will have such a sigh.

Guess you like

Origin blog.csdn.net/qq_21383435/article/details/108465972