String and JVM study notes

table of Contents

Source code

 Initialization part

 method

JVM

create

Constant pool

+and append

Interview question 1: String, StringBuffer, StringBuilder difference

Interview question 2: String a = new String("kexin"); Several objects are generated


  • Source code

  •  Initialization part

        Implemented Serializable, Comparable, CharSequence three interfaces, namely serialization, compareTo, and CharSequence, the third mainly inherited some common methods, length, charAt, subSequence, etc., subSequence is similar to subString, the effect is the same, the return value type is different , Basically do not use

     public final class String
     implements java.io.Serializable, Comparable<String>, CharSequence {
//     存储空间,字符数组形式
    private final char value[];
//    hashcode缓存,String常用于比较,每次计算太过麻烦,这样节省时间
    private int hash; 
//    序列号(尚未理解)
    private static final long serialVersionUID = -6849794470754667710L;
  •  method

copy 

//内部方法,将String的字符数组value整个复制到dst字符数组中,在dst数组的dstBegin位置开始拷贝
void getChars(char dst[], int dstBegin) {
        System.arraycopy(value, 0, dst, dstBegin, value.length);
    }


public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
        if (srcBegin < 0) {
            throw new StringIndexOutOfBoundsException(srcBegin);
        }
        if (srcEnd > value.length) {
            throw new StringIndexOutOfBoundsException(srcEnd);
        }
        if (srcBegin > srcEnd) {
            throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
        }
        System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
    }

Compared

public boolean equals(Object anObject) {
//如果对象引用地址相同
        if (this == anObject) {
            return true;
        }
//这个是?存疑
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
//字符数组长度相同
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
//每个字符相同
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

Comparison (leave to be added)

 public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = anotherString.value;

        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }

Cut

 public String substring(int beginIndex, int endIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        if (endIndex > value.length) {
            throw new StringIndexOutOfBoundsException(endIndex);
        }
        int subLen = endIndex - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
//生成新对象
        return ((beginIndex == 0) && (endIndex == value.length)) ? this
                : new String(value, beginIndex, subLen);
    }

 Replace (leave to be added)

 public String replace(char oldChar, char newChar) {
        if (oldChar != newChar) {
            int len = value.length;
            int i = -1;
            char[] val = value; /* avoid getfield opcode */

            while (++i < len) {
                if (val[i] == oldChar) {
                    break;
                }
            }
            if (i < len) {
                char buf[] = new char[len];
                for (int j = 0; j < i; j++) {
                    buf[j] = val[j];
                }
                while (i < len) {
                    char c = val[i];
//替换
                    buf[i] = (c == oldChar) ? newChar : c;
                    i++;
                }
                return new String(buf, true);
            }
        }
        return this;
    }


It can also be seen from the above source code that any changes to the String object will not affect the original object, and any related change operations will generate new objects.

  • JVM

  • create

There is a concept here, called Flyweight. My understanding is to share the existing elements in the constant pool and reduce the memory cost
. There are two ways to create:
1. String a = "a";
When creating, the jvm will judge first Whether "a" already exists in the constant pool, if it exists, it will be quoted directly, if it does not exist, the string will be instantiated and then quoted.
Finally, the reference address of "a" in the string constant pool is stored in the stack
2.String b = new String("A");
First a new string object is placed in the heap, and the heap is stored in the constant pool reference address "A", the constant pool reference address is obtained as above.
Finally, the stack is stored The reference address of the string object in the heap.
Therefore, it is impossible for two identical strings to exist in the constant pool. This is a manifestation of the immutability of strings.

 

  • Constant pool


There are two types of constant pools, static constant pool and runtime constant pool.
Compile time-static constant pool-already placed before running-constant-such as String a = "1"; String a1 = "1"+"2";
run Time-runtime constant pool-only generated at runtime-variables-such as String b = new String("1"); String b1 = "1"+b;
Note:
(1): JVM pairs String str="abc" Objects are placed in the constant pool at compile time, and String str3=str1+str2 can only be known at runtime. The new object is also done at runtime.
(2): The literal "+" splicing is performed during compilation, and the spliced ​​string is stored in the string pool; and the "+" splicing operation of the string reference is actually performed at runtime, the newly created string Store in a pile.

The static constant pool, in the class file, stores the string, class and method information, etc., which occupies most of the memory space of the class.
Runtime constant pool. After the jvm completes the class loading operation, the class constant pool is placed in the method area , Generally speaking, the constant pool refers to the constant pool in the method area
 

JVM

intern

The intern method is a native method. The intern method will query whether the current string exists from the string constant pool. If it does, it will directly return the current string; if it does not exist, it will put the current string in the constant pool and then return.

  • +and append


The + in String is interpreted as creating a StringBuffer object, calling the append() method, calling toString(), and finally destroying the StringBuffer object in the process of compiling,
such as String A= "11"+"22"+Str1+"33" ; This process is interpreted as String A = new StringBuffer("1122").append(Str).append("33").toString() at compile time;
so when the + operation needs to be performed in the loop, in fact Will consume a lot of performance in the creation and destruction of StringBuffer, it is best to manually new a StringBuffer instead of String

  • Interview question 1: String, StringBuffer, StringBuilder difference


One of the frequently asked questions in interviews
(1) Can be immutable, String is modified with final, statically immutable, and the other two are variable in length. This is why append is sometimes used instead of +. Append is expanded on the original basis, and + is Is the newly created String
(2) thread safe? String is immutable (can be understood as a constant), and there will be no conflicts caused by multiple threads changing a resource at the same time, so it is regarded as safe.
   StringBuffer uses synchronized to add synchronization locks, thread safe, StringBuffer does not exist, so it is not thread-safe
(3) Execution efficiency, relatively speaking, StringBuilder> StringBuffer> String, specific analysis of the specific situation
(4) Each feature, a small amount of data String is flexible and changeable, a large amount of data multi-threaded StringBuffer thread safety, a large amount of data Single-threaded StringBuilder is faster

 

  • Interview question 2: String a = new String("kexin"); Several objects are generated


In the class loading stage, an object "kexin" is generated and placed in the heap.
In the execution stage, an object a
is generated, so there are two


Doped portion above personal understanding, welcome to discuss and correct me
References

https://blog.csdn.net/yulungggg/article/details/81039655

https://blog.csdn.net/qq_34490018/article/details/82110578

https://www.cnblogs.com/xiaoxi/p/6036701.html

 

Guess you like

Origin blog.csdn.net/qq_36766417/article/details/107936176