Java 字符串
String 存储形式
Java 8 中,String 使用 char[]
存储字符串
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
// ...
}
Java 9 之后 String 改用 byte[]
存储,并用 coder
来标识使用了哪种编码
public final class String
implements java.io.Serializable,Comparable<String>, CharSequence {
@Stable
/** The value is used for character storage. */
private final byte[] value;
/** The identifier of the encoding used to encode the bytes*/
private final byte coder;
}
常见面试题
Q1
为什么 String 是不可变的
- value 数组被 final 修饰且为私有的,并且 String 内部没有提供修改数组的方法
- String 类被 final 修饰导致其不能被继承,从而避免了子类的修改
Q2
为什么 Java 9 之后 String 改用 byte[]
Q3
String vs StringBuilder vs StringBuffer
- String 不可变,StringBuilder, StringBuffer 可变
- String 线程安全,StringBuilder 线程不安全,StringBuffer 线程安全
String 拼接
一般来说,如果涉及大量字符串拼接操作,建议使用 StringBuilder
String 常量池
String s1 = "a";
String s2 = "b";
String s3 = "ab"; // constant pool
String s4 = "a" + "b"; // constant pool
String s5 = s1 + s2; // heap
String s6 = new String("ab"); // heap
System.out.println(s3 == s4); // true
System.out.println(s3 == s5); // false
System.out.println(s3 == s6); // false
System.out.println(s4 == s5); // false
System.out.println(s4 == s6); // false
System.out.println(s5 == s6); // false
如果在前面加上 final
final String s1 = "a";
final String s2 = "b";
String s3 = "ab"; // constant pool
String s4 = "a" + "b"; // constant pool
String s5 = s1 + s2; // constant pool
System.out.println(s3 == s5); // true
System.out.println(s4 == s5); // true