The internal implementation of the substring method in the String class and a detailed explanation of the memory leak

Before JDK7, the new object created by the substring method in the String class pointed to the same array as the original object, specifically:

/**JDK6*/
public final class String {
    
    
	 /** The value is used for character storage. */
    private final char value[];
 
    /** The offset is the first index of the storage that is used. */
    private final int offset;
 
    /** The count is the number of characters in the String. */
    private final int count;

    /** 在下面substring中创建新的String对象时使用了改构造函数 */
    public String(int offset, int count, char value[]) {
    
    
    /**第一处*/
        this.value = value;
        this.offset = offset;
        this.count = count;
    }

    public String substring(int beginIndex, int endIndex) {
    
    
    	if (beginIndex < 0) {
    
    
    	    throw new StringIndexOutOfBoundsException(beginIndex);
    	}
    	if (endIndex > count) {
    
    
    	    throw new StringIndexOutOfBoundsException(endIndex);
    	}
    	if (beginIndex > endIndex) {
    
    
    	    throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
    	}
    /**第二处*/
    	return ((beginIndex == 0) && (endIndex == count)) ? this :
    	    new String(offset + beginIndex, endIndex - beginIndex, value);
    }
}

Insert picture description here
Determining in the second condition is satisfied after beginIndex and endIndex a new String object, as shown in FIG. In the process of new, the String (int offset, int count, char value[]) construction method is used. This method just re-assigns the member variables, so both the old and new String objects point to the same array.

Starting from JDK7, the newly created object in the substring method and the original String object point to a different array, as follows:

/**JDK7*/
public final class String {
    
    
	 /** The value is used for character storage. */
    private final char value[];
 
    /** The offset is the first index of the storage that is used. */
    private final int offset;
 
    /** The count is the number of characters in the String. */
    private final int count;
    
    public String(char value[], int offset, int count) {
    
    
        if (offset < 0) {
    
    
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count < 0) {
    
    
            throw new StringIndexOutOfBoundsException(count);
        }
        // Note: offset or count might be near -1>>>1.
        if (offset > value.length - count) {
    
    
            throw new StringIndexOutOfBoundsException(offset + count);
        }
    /**第一处*/
        this.value = Arrays.copyOfRange(value, offset, offset+count);
    }
    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);
    }
}
/**Arrays.copyOfRange*/
public static char[] copyOfRange(char[] original, int from, int to) {
    
    
    int newLength = to - from;
    if (newLength < 0)
        throw new IllegalArgumentException(from + " > " + to);
    char[] copy = new char[newLength];
    System.arraycopy(original, from, copy, 0,
                     Math.min(original.length - from, newLength));
    return copy;
}

Insert picture description here
Compared with JDK6, the second construction method is changed. The construction method assigns member variables through this.value = Arrays.copyOfRange(value, offset, offset+count). Check the static method of Arrays copyOfRange and find that the method is newly created Create a copy object and return, that is to say, through the construction method, the old and new String objects no longer point to the same place, as shown in the figure above.

Reference link
https://blog.csdn.net/du_an_a_nuo/article/details/50853046
https://blog.csdn.net/u010293702/article/details/46560289
https://www.cnblogs.com/treeAndCloud/p/ 7249266.html

Guess you like

Origin blog.csdn.net/weixin_48968045/article/details/112297991