public String concat(String str) { int otherLen = str.length(); if (otherLen == 0) { return this; } int len = value.length; char buf[] = Arrays.copyOf(value, len + otherLen); str.getChars(buf, len); return new String(buf, true);}
public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence {/** The value is used for character storage. */private final char value[];}
可以看得出, String 类其实是通过操作字符数组 value 实现的。而 value 是 private 的,也没有提供
serValue()
这样的方法进行修改;况且 value 还是 final 的,意味着 value 一旦被初始化,就无法进行改变。
另外呢,String 类提供的方法,比如说
substring()
:
public String substring(int beginIndex) {int subLen = value.length - beginIndex;return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);}toLowerCase():public String toLowerCase(Locale locale) {return new String(result, 0, len + resultOffset);}
还有之前提到的
concat()
,看似都能改变字符串的内容,但其实都是在方法内部使用 new 关键字重新创建的新字符串对象。
04. 为什么要不可变
String 类的源码中还有一个重要的字段 hash,用来保存字符串对象的 hashCode。
public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence { /** Cache the hash code for the string */ private int hash; // Default to 0 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; }}