Summary of some details of the Java String class

valueThis article mainly introduces the member variables and intern()methods in the String class ==and equals()their differences.

valueMember variables

Before introducing this member variable, I would like to talk about why Java introduces the concept of constant pool.

We mean that every time we create a string, we need to allocate a piece of memory space. If we include strings with the same content in different places in the program, it will cause memory waste. At this time, we naturally hope to create a string every time. Save them all, and if you need the same string in the future, just reuse the reference of the saved string. All in all, the purpose of the constant pool is to save memory.

Then valueit is used to do this, and it stores the content contained in the string. When creating a String object, the literal reference passed in is used as valuethe value.

This literal value will first be searched in the constant pool, and if it is found, it will return the reference of the string corresponding to the constant pool. If it cannot find it, it will create a new string in the constant pool and return its reference.

But valueit is not always a reference to a string in the constant pool, such as:

String str = new String("ab") + new String("c");

strThe stored value of the object valuewill not be the value of the string in the constant pool, because this is the addition of two variables and cannot be uniquely determined at compile time . As for why it is impossible to determine when compiling, please see the following example:

public class MyTest {
    
    
    static final String a = "ab";
    static final String b = "c";
    public static void main(String[] args) {
    
    
        String c = a + b;
        System.out.println(c == "abc");
    }
}

This code will output true, if finaldeleted, become false. This actually shows that if it can be uniquely determined at compile time, then the compiler will make corresponding optimizations during the process of compiling into a .class file.

In fact, not only the above situation will be optimized, but for the addition of string constants:

String str= "ab" + "cd" + "ef";

will become

String str= "abcdef";

For addition of string variables:

String str = "abcdef"; 

for(int i=0; i<1000; i++) {
    
     
  str = str + i; 
} 

will become

String str = "abcdef"; 

for(int i=0; i<1000; i++) {
    
     
  str = (new StringBuilder(String.valueOf(str))).append(i).toString(); 
} 

In addition to the above, in fact, the literal string constants we write down when we write code, for example "abc", will be optimized into a String object during compilation. Specifically, if multiple literal string constants have the same value, the compiler will merge them into the same String object and generate corresponding constant references in the constant pool of the class.

intern()method

The method before and after JDK7 intern()is different in the underlying implementation. This method is used to return the reference of the string in the constant pool.

intern()Method signature:public native String intern()();

Before JDK7

When creating a string object through the String constructor, intern()the method will first check whether there is a corresponding string constant in the constant pool, if not, copy a copy to the constant pool, and then return the reference to the copied string in the constant pool

After JDK7

If not in the constant pool, then only the reference of the String object will be recorded in the constant pool , and no string constant will be copied in the constant pool.

Reference link: From java.lang.String#intern, the difference between the string constant pool before JDK6 and JDK7 and after

#The difference ==with equals()the method
With the above foundation, it will be much easier to understand the difference between the two.

For complex types of data, ==it is actually comparing the hash codes of the two.

The default hash code generation seems to be based on the memory address of the object.

So new String("abc")and "abc"are not equal, because they are basically not the same object , but obviously we generally think that as long as the string content is the same, it is the same object, so at this time, equals()the method should be rewritten to determine whether they are equal, but this requirement is due to too much Common, Java has already done it for us - rewriting equals()methods.

This is actually the old-fashioned question-why rewriting hashCode()the method must re- equals()method.

This is because hashCode()after the method is rewritten, APIs such as collections will judge whether the objects are equal based on this, but we know that hash functions always inevitably collide , so different objects may also have calculated hash codes that are equal. At this time If we don't override equals()the method, then basically 100% there will be problems.

Because the default equals()method is to judge whether two objects are equal according to the memory address, then they must not be equal, because we think Person p1 = new Person("小明");and Person p2 = new Person("小明");are the same object, even if we actually created two objects.

Guess you like

Origin blog.csdn.net/weixin_55658418/article/details/130452547