String 类被定义为 final,实现了 SerializableComparableCharSequence 接口。

String 的值是 char 类型数组。

private final char value[];

在方法 isEmpty() 中,判断的其实就是字符串的长度,长度为 0 返回 true。

public boolean isEmpty() {
    return value.length == 0;
}

我们平常使用的 equals 方法比较的就是两个字符数组是否想等。

public boolean equals(Object anObject) {
    // 若两个对象地址相等,直接返回 true
    if (this == anObject) {
        return true;
    }
    // 只有在参数是 String 类型时才相等
    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;
}

在参数为 StringBuffer 类型和 StringBuilder 类型的构造方法中,可以看出,对于 StringBuffer 的线程不安全性做了处理,使用锁将参数锁起来,防止其他地方进行修改。

public String(StringBuffer buffer) {
    synchronized(buffer) {
        this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
    }
}
public String(StringBuilder builder) {
    this.value = Arrays.copyOf(builder.getValue(), builder.length());
}

StringStringBufferStringBuilder 也可以判等,比较的是他们的字符序列。

public boolean contentEquals(StringBuffer sb) {
    // 将 StringBuffer 转为字符序列和 String 的字符序列进行比较
    return contentEquals((CharSequence)sb);
}
public boolean contentEquals(CharSequence cs) {
    // 参数是一个 StringBuffer, StringBuilder
    if (cs instanceof AbstractStringBuilder) {
        if (cs instanceof StringBuffer) {
            // StringBuffer 要注意线程安全
            synchronized(cs) {
                return nonSyncContentEquals((AbstractStringBuilder)cs);
            }
        } else {
            return nonSyncContentEquals((AbstractStringBuilder)cs);
        }
    }
    // 参数是一个 String
    if (cs instanceof String) {
        return equals(cs);
    }
    // 参数是一个普通的字符序列
    char v1[] = value;
    int n = v1.length;
    if (n != cs.length()) {
        return false;
    }
    for (int i = 0; i < n; i++) {
        if (v1[i] != cs.charAt(i)) {
            return false;
        }
    }
    return true;
}

Java 源码分析 — String 的设计