public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /**char数组用于字符的存储 */ private final char value[]; /** 缓存string的hash码 */ private int hash; // Default to 0 public String() {/**无参构造函数,打印值为""*/ this.value = new char[0]; } public String(String original) {/**字符值和hash值均为参数的值*/ this.value = original.value; this.hash = original.hash; } public String(char value[]) {/**Arrays.copyOf()方法返回一个新构造的 char数组*/ this.value = Arrays.copyOf(value, value.length); } 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); } /**传入代码点来构造String对象,代码点和代码单元相关内容可自行查阅资料,或者看我另一篇随笔深入学习Java中的字符串,代码点和代码单元*/
public String(int[] codePoints, 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 > codePoints.length - count) { throw new StringIndexOutOfBoundsException(offset + count); } final int end = offset + count; /**计算char数组的真实大小,一个代码点有可能需要用2个char即2个代码单元表示*/ int n = count; for (int i = offset; i < end; i++) { int c = codePoints[i]; if (Character.isBmpCodePoint(c))/**此代码点为基本字符代码点*/ continue; else if (Character.isValidCodePoint(c))/**此代码点为有效代码点,即辅助字符代码点,此时一个代码点需要用2个char即2个代码单元表示,n++*/ n++; else throw new IllegalArgumentException(Integer.toString(c)); } /**分配并填充字符数组*/ final char[] v = new char[n]; for (int i = offset, j = 0; i < end; i++, j++) { int c = codePoints[i]; if (Character.isBmpCodePoint(c)) v[j] = (char)c; else Character.toSurrogates(c, v, j++); } this.value = v; } /**返回指定下标的字符*/ public char charAt(int index) { if ((index < 0) || (index >= value.length)) { throw new StringIndexOutOfBoundsException(index); } return value[index]; } /**返回指定下标的代码点*/ public int codePointAt(int index) { if ((index < 0) || (index >= value.length)) { throw new StringIndexOutOfBoundsException(index); } return Character.codePointAtImpl(value, index, value.length); } public boolean equals(Object anObject) { if (this == anObject) { return true;/**如果是同一个对象,直接返回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; } public boolean contentEquals(StringBuffer sb) { synchronized (sb) {/**锁定StringBuffer对象,防止修改*/ return contentEquals((CharSequence) sb); } } public boolean equalsIgnoreCase(String anotherString) { return (this == anotherString) ? true : (anotherString != null) && (anotherString.value.length == value.length) && regionMatches(true, 0, anotherString, 0, value.length); } /**计算并返回hsah码*/ public int hashCode() { int h = hash;/**默认是0*/ 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 String substring(int beginIndex) { if (beginIndex < 0) { throw new StringIndexOutOfBoundsException(beginIndex); } int subLen = value.length - 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[] = Arrays.copyOf(value, len + otherLen); str.getChars(buf, len);/**将str内的字符依次存放到buf数组中,下标从len开始*/ return new String(buf, true);/**返回新生成的对象*/ } /**trim()方法将字符串首尾的ascii码数值小于或等于空格的字符删除*/ public String trim() { int len = value.length; int st = 0; char[] val = value; /* avoid getfield opcode */ while ((st < len) && (val[st] <= ' ')) {/**从字符串首个字符开始判断ascii是否小于或等于空格,若小于或等于,计数++*/ st++; } while ((st < len) && (val[len - 1] <= ' ')) {/**从字符串最后一个字符开始判断ascii是否小于或等于空格,若小于或等于,计数--* len--; } return ((st > 0) || (len < value.length)) ? substring(st, len) : this; } /**返回自身对象的引用*/ public String toString() { return this; } /**和toString()唯一区别就是先判断对象是否为空*/ public static String valueOf(Object obj) { return (obj == null) ? "null" : obj.toString(); }