Interview Question Series Part 2: How many objects does new String() create? Something you don't know

Java Interview Questions Series: Write the more classic and core content of the interview questions into a series of articles and continue to update on the official account, which can consolidate basic knowledge and sort out the underlying principles. Welcome everyone to continue to pay attention to [Program New Vision]. This is the second in the interview question series.

Common interview questions

How many objects are created in the following code?

new String("abc");

The answer is different. Some say that 1 object is created, and some say that 2 objects are created. The answer is right and wrong. The key is to learn the underlying principles of the problem.

Analysis of the underlying principle

In the previous article " Interview Question Series No. 1: What is the difference between == and equals? Your answer may be wrong . We have already mentioned that the two initialization forms of String are essentially different.

String str1 = "abc";  // 在常量池中

String str2 = new String("abc"); // 在堆上

When assigning directly, the string "abc" will be stored in the constant pool, and there will be only one copy. At this time, the assignment operation is equivalent to creating 0 or 1 objects. If "abc" already exists in the constant pool, then no object will be created, and the reference will be assigned to str1; if there is no "abc" in the constant pool, then an object will be created and the reference will be assigned to str1.

So, what about the form of passing new String("abc");? The answer is one or two.

When the JVM encounters the above code, it will first search for the existence of "abc" in the constant pool. If the string "abc" does not exist, it will first create this string in the constant pool. Then perform the new operation, a String object storing "abc" will be created in the heap memory, and the reference of the object will be assigned to str2. This process creates 2 objects.

Of course, if the corresponding string is found when the constant pool is retrieved, only a new String object will be created in the heap, and only one object will be created in this process.

In the above process, when checking whether the constant pool has the same Unicode string constant, the method used is the intern() method in String.

public native String intern();

Let's look at the two storage modes of String in memory through a simple schematic diagram.
image

In the above diagram, we can see that the char value[] property of the String object created in the heap points to the char value[] in the constant pool.

Still the above example, if we pass the debug mode, we can also see the reference address of String's char value[].

image

The references of the value values ​​of the two String objects in the figure are both {char[3]@1355}, that is, although they are two objects, their value values ​​all point to the same address in the constant pool. Of course, you can also compare the debug results when the string attribute (name) of a complex object (Person) is the same, and the result is the same.

In-depth questioning

If the interviewer says that the program code has only the following line, how many objects will be created?

new String("abc");

The answer is 2?

Really not necessarily. The reason for listing this issue separately is to remind everyone that there is no direct assignment operation (str="abc"), which does not mean that there is no string "abc" in the constant pool. That is to say, to measure the creation of several objects and whether there is a corresponding string in the constant pool is not only determined by whether you create it, but also whether the string is included in other classes when the program starts.

Upgrade plus code

In the following example, we do not consider whether the corresponding string already exists in the constant pool, assuming that there is no corresponding string.

The following code creates several objects:

String str = "abc" + "def";

The above question involves the problem of string constant overloading "+". When a string is concatenated from multiple string constants into a string, it must be a string constant itself. The "+" sign of the string constant is connected to the Java virtual machine to optimize it to the connected value during program compilation.

As for the above example, it has been merged into the "abcdef" string at compile time, so only one object will be created. The temporary string objects abc and def are not created, which reduces the pressure on the garbage collector.

We can see the following content by viewing the class file through javap.
Insert picture description here

Obviously, there is only the spliced ​​abcdef in the bytecode.

In response to the above problem, let's upgrade again. How many objects will the following code create?

String str = "abc" + new String("def");

Are 4, 5, or 6 objects created?

Four objects: "abc" and "def" in the constant pool, and new String ("def") and "abcdef" in the heap.

Is this statement right? Not exactly right, if the above code creates several string objects, then it can be said to be correct. However, the above code Java virtual machine will also be optimized when compiling, and a StringBuilder will be created to concatenate strings. The actual effect is similar:

String s = new String("def");
new StringBuilder().append("abc").append(s).toString();

Obviously, there is one more StringBuilder object, which should be five objects.

So what is the matter of creating 6 objects? Some students might think, isn’t the "abcdef" after the last toString() of StringBuilder not saved in the constant pool?

This is really not saved, let's take a look at this code:

@Test
public void testString3() {
	String s1 = "abc";
	String s2 = new String("def");
	String s3 = s1 + s2;
	String s4 = "abcdef";
	System.out.println(s3==s4); // false
}

According to the above analysis, if the result of s1+s2 is stored in the constant pool, then the value reference in s3 should be the same as the value reference in s4. Let's look at the effect of debug below.

image

Obviously, the values ​​of s3 and s4 are the same, but the address of the value value is not the same. Even if you adjust the positions of s3 and s4, the effect is the same. S4 clearly exists in the constant pool, so where is the value of s3 stored? Obviously it is in the heap object.

Let's take a look at how the toString() method of StringBuilder converts the splicing result into a string:

@Override
public String toString() {
    // Create a copy, don't share the array
    return new String(value, 0, count);
}

Obviously, a new String object is created in the toString method, and the String object is created by passing the array constructor:

public String(char value[], int offset, int count) 

In other words, the value value of the String object directly points to an existing array, but does not point to the string in the constant pool.

Therefore, the accurate answer above should be to create 4 string objects and 1 StringBuilder object.

summary

We gradually analyzed the entire construction and splicing process of String objects through a line of code to create strings, and understood the underlying implementation principles. Isn’t it interesting? Once you have mastered these basic knowledge, even if the format of the interview questions changes, you will surely be able to see the truth at a glance.

In the next article, (reader's suggestion) we will talk about the underlying logic of Integer's comparison. We welcome continued attention.

Original link: " Interview Question Series Part 2: How many objects does new String() create?" There you do not know . "


New Vision of Procedure

The public account " New Vision of Program ", a platform that allows you to simultaneously improve your soft power and hard technology, providing massive amounts of data

WeChat Official Account: New Vision of Program

Guess you like

Origin blog.csdn.net/wo541075754/article/details/108212654