String可能是Java中使用频率最高的引用类型,因此String类的设计者是精心打磨。
比如String的不可变。
String被final关键字修饰,所以不可以有子类,就意味着没有子类可以重写它的方法,改变它的行为。
String 类的数据存储在 char[] 数组中,而这个数组也被 final 关键字修饰了,这就表示 String 对象是没法被修改的,只要初始化一次,值就确定了。
这里是char,说明是旧版本(9)
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
}
第一,可以保证String对象的安全性,避免被篡改,毕竟像密码这样的隐私信息就是使用字符串存储的。
第二,保证哈希值不会频繁变更,因为String要经常作为哈希表的键值,经常变更的话,哈希表的性能就会很差劲。
在String类中,哈希值是在第一次计算时缓存的,后续对该哈希值的请求将直接使用哦缓存值。这将有助于提高哈希表等数据结构的性能。
第三,可以实现字符串常量池,Java会将相同内容的字符串存储在字符串常量池中。这样,具有相同内容的字符串变量可以指向同一个String对象,节省内存空间。
由于字符串的不可变性,String类的一些方法实现最终都返回了新的字符串对象。
就拿substring来说
public String substring(int beginIndex, int endIndex) {
int length = length();
checkBoundsBeginEnd(beginIndex, endIndex, length);
if (beginIndex == 0 && endIndex == length) {
return this;
}
int subLen = endIndex - beginIndex;
return isLatin1() ? StringLatin1.newString(value, beginIndex, subLen)
: StringUTF16.newString(value, beginIndex, subLen);
}
substring()方法用于截取字符串,最终返回的都是new出来的新字符串对象。
还有concat()方法
public String concat(String str) {
if (str.isEmpty()) {
return this;
}
return StringConcatHelper.simpleConcat(this, str);
}
@ForceInline
static String simpleConcat(Object first, Object second) {
String s1 = stringOf(first);
String s2 = stringOf(second);
if (s1.isEmpty()) {
// newly created string required, see JLS 15.18.1
return new String(s2);
}
if (s2.isEmpty()) {
// newly created string required, see JLS 15.18.1
return new String(s1);
}
// start "mixing" in length and coder or arguments, order is not
// important
long indexCoder = mix(initialCoder(), s1);
indexCoder = mix(indexCoder, s2);
byte[] buf = newArray(indexCoder);
// prepend each argument in reverse order, since we prepending
// from the end of the byte array
indexCoder = prepend(indexCoder, buf, s2);
indexCoder = prepend(indexCoder, buf, s1);
return newString(buf, indexCoder);
}
concat()方法用于拼接字符串,不管编码是否一致,最终也返回的是新的字符串对象。
replace()替换方法其实也一样,这就意味着,不管是截取、拼接、还是替换,都不是在原有的字符串上进行的,而是重新生成了新的字符串对象,也就是说,这些操作过后,原来的字符串对象并没有发生改变。
206

被折叠的 条评论
为什么被折叠?



