package java.lang;
public final class String
implements java.io.Serializable, Comparable
// 核心:字符数组,存储字符串内容
private final char value[];// 缓存哈希值,默认 0
private int hash;// 序列化版本号
private static final long serialVersionUID = -6849794470754667710L;// 空字符串构造
public String() {this.value = "".value;
}
public String(String original) {this.value = original.value;this.hash = original.hash;
}
public String(char value[]) {this.value = java.util.Arrays.copyOf(value, value.length);
}
public int length() {return value.length;
}
public char charAt(int index) {if ((index < 0) || (index >= value.length)) {throw new StringIndexOutOfBoundsException(index);}return value[index];
}
public int hashCode() {int h = hash;if (h == 0 && value.length > 0) {char val[] = value;for (int i = 0; i < value.length; i++) {h = 31 * h + val[i];}hash = h;}return h;
}
public substring(int beginIndex) {int subLen = value.length - beginIndex;if (beginIndex < 0) {throw new StringIndexOutOfBoundsException(beginIndex);}if (subLen < 0) {throw new StringIndexOutOfBoundsException(subLen);}return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
}
public String concat(String str) {int otherLen = str.length();if (otherLen == 0) {return this;}int len = value.length;char buf[] = new char[len + otherLen];System.arraycopy(value, 0, buf, 0, len);str.getChars(buf, len);return new String(buf, true);
}
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;
}
}
源码中 String 被 final 修饰、底层存储字符的 char[] value 也被 private final 修饰,双重限制让字符串一旦创建就无法修改。我们日常使用的 substring() 、 concat() 、 replace() 等看似修改字符串的方法,本质都不是修改原对象,而是新建一个字符串对象并返回。
这让我明白:Java中字符串“修改”只是表象,底层永远是新建对象,这也是频繁拼接字符串不建议直接用 + ,要使用 StringBuilder 的根本原因。
