以下代码只挑选了关键方法进行分析
public final class String //String类不可继承,实现了序列化 implements java.io.Serializable, Comparable<String>, CharSequence { private final char value[]; //String底层就是一个char数组 private int hash; // Default to 0 private static final long serialVersionUID = -6849794470754667710L; private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0]; public String() { //默认返回空字符串 this.value = "".value; } public String(String original) { this.value = original.value; this.hash = original.hash; } public int compareTo(String anotherString) {
//当前字符串v1和另一串v2比较,根据两者最小长度遍历,逐个字符进行比较,若发现不同的字符串就返回v1[k]-v2[k], //若遍历完发现全部相同,则返回v1.len-v2.len int len1 = value.length; int len2 = anotherString.value.length; int lim = Math.min(len1, len2); char v1[] = value; char v2[] = anotherString.value; int k = 0; while (k < lim) { char c1 = v1[k]; char c2 = v2[k]; if (c1 != c2) { return c1 - c2; } k++; } return len1 - len2; } public boolean equals(Object anObject) {
//首先比较两者的内存地址,若相同则返回true;
//若anObject属于String类型,则转换为String类型,在两者的长度相等的前提下,逐个字符进行比较。 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; } public static String valueOf(Object obj) {
/*
String a1 = "无论字符串是多少,使用==比较时,永远返回true";
String a2 = "无论字符串是多少,使用==比较时,永远返回true";
String a3 = null;
System.out.println(a1==a2); // true
System.out.println("a1:"+a1.hashCode()+" a2:"+a2.hashCode()); //a1:-1368761767 a2:-1368761767
System.out.println("若给a3赋值null,则返回一个字符串'null' :"+a3);//若给a3赋值null,则返回一个字符串'null' :null
String b1 = new String("aa");//若使用new String()声明,使用==返回false,因为地址不同
String b2 = new String("aa");
System.out.println(b1 == b2);// false
System.out.println("b1:"+b1.hashCode()+" b2:"+b2.hashCode()); //b1:3104 b2:3104
*/ return (obj == null) ? "null" : obj.toString(); } public static String valueOf(char data[]) { return new String(data); }
public int hashCode() {
/*
这里计算字符串的hash码如下,hash默认为0,若字符串长度大于0,则遍历字符串,算法公式:h = 31 * h + val[i]
*/ 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 final class StringBuffer //StringBuffer和StringBulider最大的区别是前者线程安全,后者线程不安全,其他的功能基本相同,
//两者都继承了AbstractStringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence{ @Override public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; } @Override public synchronized String toString() { if (toStringCache == null) { toStringCache = Arrays.copyOfRange(value, 0, count); } return new String(toStringCache, true); } } public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence{ @Override public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; } @Override public String toString() { // Create a copy, don't share the array return new String(value, 0, count); } } abstract class AbstractStringBuilder implements Appendable, CharSequence { char[] value; int count; AbstractStringBuilder() { } AbstractStringBuilder(int capacity) { value = new char[capacity]; } public AbstractStringBuilder append(String str) { if (str == null) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars(0, len, value, count); count += len; return this;
/*String类的getChars()
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
if (srcBegin < 0) {
throw new StringIndexOutOfBoundsException(srcBegin);
}
if (srcEnd > value.length) {
throw new StringIndexOutOfBoundsException(srcEnd);
}
if (srcBegin > srcEnd) {
throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
}
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}
*/ } private void ensureCapacityInternal(int minimumCapacity) { // overflow-conscious code if (minimumCapacity - value.length > 0) expandCapacity(minimumCapacity); } void expandCapacity(int minimumCapacity) {//数组扩容 int newCapacity = value.length * 2 + 2; if (newCapacity - minimumCapacity < 0) newCapacity = minimumCapacity; if (newCapacity < 0) { if (minimumCapacity < 0) // overflow throw new OutOfMemoryError(); newCapacity = Integer.MAX_VALUE; } value = Arrays.copyOf(value, newCapacity); } }
public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence{ //线程安全的 @Override public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; } @Override public synchronized String toString() { if (toStringCache == null) { toStringCache = Arrays.copyOfRange(value, 0, count); } return new String(toStringCache, true); } } public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence{ //线程不安全,是两者最大的区别,两者的实现代码基本类似 @Override public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; } @Override public String toString() { // Create a copy, don't share the array return new String(value, 0, count); } } abstract class AbstractStringBuilder implements Appendable, CharSequence { char[] value; int count; AbstractStringBuilder() { } AbstractStringBuilder(int capacity) { value = new char[capacity]; } public AbstractStringBuilder append(String str) { if (str == null) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars(0, len, value, count); count += len; return this; } private void ensureCapacityInternal(int minimumCapacity) { // overflow-conscious code if (minimumCapacity - value.length > 0) expandCapacity(minimumCapacity); } void expandCapacity(int minimumCapacity) { int newCapacity = value.length * 2 + 2; if (newCapacity - minimumCapacity < 0) newCapacity = minimumCapacity; if (newCapacity < 0) { if (minimumCapacity < 0) // overflow throw new OutOfMemoryError(); newCapacity = Integer.MAX_VALUE; } value = Arrays.copyOf(value, newCapacity); } }