Recently I saw an interview question about the String class. It seems that I still didn’t understand some concepts when I was learning the basics of Java, so I started researching and finally came up with this article:
I can’t remember the title clearly, but the content is similar — please state the reason why the following situation occurs:
public class Test {
public static void main(String[] args){
String s1 = "str";
String s2 = "ing";
String s3 = "string";
String s4 = s1 + s2;
long hash = s3.hashCode();
System.out.println("s3: "+s3.hashCode());
System.out.println("s4: "+s4.hashCode());
System.out.println("s3.hashCode==s4.hashCode:"+ (hash==s4.hashCode()));
System.out.println("s3==s4:"+(s3==s4));
System.out.println("s3.equals(s4):"+ s3.equals(s4)); }}Copy the code
What I don’t understand is whether objects after String concatenation will be shared in the object pool. Here are a few questions to learn about String objects
What is the relationship between the concatenated string and the string in the string object pool?
First of all, String concatenation S1 + s2 is actually a Syntax sugar in Java. It uses StringBuilder to concatenate strings. After concatenation, it uses the new keyword to generate and return a new String object. Both strings have different memory addresses, so s3! = s4), it is not automatically added to the String constant pool after concatenation (instead, it can be added to the String constant pool using intern. If there is already a String with the same hashCode in the pool, the memory address of the String is returned. Add to object pool if no)
Summary: The concatenated String in Java is a new String created by the StringBuilder class using the new keyword.
So whyString str = new String("string");
Can’t add a string to a string constant pool?
Because using the new keyword to create an object will allocate memory directly in the heap and then instantiate it, return the address, don’t go through the string constant pool to check if the string already exists, return the address of the object in the constant pool
Isn’t hashCode the result of an operation on the object store address? Why is hashCode the same as the string in the object pool?
The hashCode() method does not represent the address of the object store. If two objects are equal after ==, then hashCode must be equal.
However, hashCode can also be equal if two objects are not equal, a situation called hash collision, and the essence of S3 and S4 is that two different references refer to two different memory regions (two different memory regions in the JVM’s heap memory), except that the strings have the same value, so equals determines that the two objects are the same. “==” compares whether the memory address of two objects is the same, so the result is false. In addition, the hashCode and equals methods of the String class have been overridden, and their analysis will be covered later.
When a string is put into the string constant pool:
Literal:
In computer science, a literal is the notation used to express a fixed value in source code. Almost all computer programming languages have literal representations of basic values such as integers, floating point numbers, and strings. Many also support literal representations for Boolean and character values; Others support literal representation even for elements of enumerated type and values of compound types such as arrays, records, and objects. — Baidu Encyclopedia
Values such as: int a = 10; A is the variable, 10 is the literal,
When is a string put into the string constant pool?
- In the first case, the literal of the string is actually put into the string constant pool after it is recognized by the compiler:
public class Test {
public static void main(String[] args){
System.out.println("string".hashCode());
String s1 = "string";
System.out.println(s1.hashCode());
System.out.println(s1=="string"); }} console: -891985903
-891985903
true
Copy the code
Because the string literal appears in line 3 of the output statement, the compiler recognizes the “string” literal and adds it to the string constant pool, and then when it assigns “string” to S1 on line 4, since the string constant pool already has a “string” object, So s1 is assigned the return address of the object in the string constant pool, which is why line 7 outputs true.
- In the second case, the programmer actively calls the intern method and puts it into the string constant pool:
public native String intern(a);
Copy the code
However, since intern is a native method, I will not analyze the source code for now. If there is an object in the constant pool that is equal to the value of the String object, it returns the address of the object in the constant pool. If there is no object in the constant pool, it creates a String object and returns the address of the newly created object
Conclusion:
- The String class is added to the String constant pool if: 1. Literals appear in the code. 2. Actively call intern() method
- If the target String already exists in the constant pool, the object that creates the new String using declarative assignment returns the address of the object in the constant pool
- A new string created using the new keyword will not be added to the constant pool.