/** * The value is used for character storage. * * @implNote This field is trusted by the VM, and is a subject to * constant folding if String instance is constant. Overwriting this * field after construction will cause problems. * * Additionally, it is marked with {@link Stable} to trust the contents * of the array. No other facility in JDK provides this functionality (yet). * {@link Stable} is safe here, because value is never null. */ @Stable privatefinalbyte[] value;
/** * Returns the length of this string. * The length is equal to the number of <a href="Character.html#unicode">Unicode * code units</a> in the string. * * @return the length of the sequence of characters represented by this * object. */ publicintlength(){ return value.length >> coder(); }
/** * Concatenates the specified string to the end of this string. * <p> * If the length of the argument string is {@code 0}, then this * {@code String} object is returned. Otherwise, a * {@code String} object is returned that represents a character * sequence that is the concatenation of the character sequence * represented by this {@code String} object and the character * sequence represented by the argument string.<p> * Examples: * <blockquote><pre> * "cares".concat("s") returns "caress" * "to".concat("get").concat("her") returns "together" * </pre></blockquote> * * @param str the {@code String} that is concatenated to the end * of this {@code String}. * @return a string that represents the concatenation of this object's * characters followed by the string argument's characters. */ public String concat(String str){ if (str.isEmpty()) { returnthis; } if (coder() == str.coder()) { byte[] val = this.value; byte[] oval = str.value; int len = val.length + oval.length; byte[] buf = Arrays.copyOf(val, len); System.arraycopy(oval, 0, buf, val.length, oval.length); returnnew String(buf, coder); } int len = length(); int olen = str.length(); byte[] buf = StringUTF16.newBytesFor(len + olen); getBytes(buf, 0, UTF16); str.getBytes(buf, len, UTF16); returnnew String(buf, UTF16); // 返回一个新的数组 }
/** * Replaces each substring of this string that matches the literal target * sequence with the specified literal replacement sequence. The * replacement proceeds from the beginning of the string to the end, for * example, replacing "aa" with "b" in the string "aaa" will result in * "ba" rather than "ab". * * @param target The sequence of char values to be replaced * @param replacement The replacement sequence of char values * @return The resulting string * @since 1.5 */ public String replace(CharSequence target, CharSequence replacement){ String tgtStr = target.toString(); String replStr = replacement.toString(); int j = indexOf(tgtStr); if (j < 0) { returnthis; } int tgtLen = tgtStr.length(); int tgtLen1 = Math.max(tgtLen, 1); int thisLen = length();
int newLenHint = thisLen - tgtLen + replStr.length(); if (newLenHint < 0) { thrownew OutOfMemoryError(); } StringBuilder sb = new StringBuilder(newLenHint); // 调用 StringBuilder int i = 0; do { sb.append(this, i, j).append(replStr); i = j + tgtLen; } while (j < thisLen && (j = indexOf(tgtStr, j + tgtLen1)) > 0); return sb.append(this, i, thisLen).toString(); } }
abstractclassAbstractStringBuilderimplementsAppendable, CharSequence{ /** * The value is used for character storage. */ byte[] value; /** * The id of the encoding used to encode the bytes in {@code value}. * 即指定的编码格式,从而确定每个 字符占用的 byte 数 */ byte coder;
/** The count is the number of characters used. */ int count;
/** * For positive values of {@code minimumCapacity}, this method * behaves like {@code ensureCapacity}, however it is never * synchronized. * If {@code minimumCapacity} is non positive due to numeric * overflow, this method throws {@code OutOfMemoryError}. */ privatevoidensureCapacityInternal(int minimumCapacity){ // overflow-conscious code // 位移主要是编码格式的问题,实现 byte[] 长度到字符长度的转换 int oldCapacity = value.length >> coder; if (minimumCapacity - oldCapacity > 0) { // 调用 Arrays.copyOf 函数更新 byte[] 数组长度 value = Arrays.copyOf(value, newCapacity(minimumCapacity) << coder); } }
public AbstractStringBuilder append(String str){ if (str == null) { return appendNull(); } int len = str.length(); ensureCapacityInternal(count + len); putStringAt(count, str); count += len; returnthis; } }