参考知乎文章:https://zhuanlan.zhihu.com/p/29629508
常量池- 静态常量池
class字节码文件中的字符串、数字字面量以及类、方法的信息 - 运行时常量池
class字节码文件被jvm加载后,其包含的静态常量池会被加载到内存中的方法区里
总结:常量池可以有效的避免字符串对象的重复创建
- 【直接创建】
String ab = “ab”;
jvm优先去常量池中查找是否存在"ab"对象,不存在则在字符串常量池中创建"ab"对象,然后将"ab"对象的引用地址返回给字符串常量ab - 【常量拼接】
String ab1 = “a” + “b”;
编译期间会合并这2个字符串常量为常量"ab",再去常量池中查找是否存在"ab"对象… - 【变量拼接】
String a = “a”;
String b = “b”;
String ab2 = a + b;
涉及到字符串变量拼接,会调用StringBuilder.append()在堆上创建新的对象 - 【new关键字】
String ab3 = new String(“ab”);
new创建的字符串不是常量,不能在编译期确定,所以其不放入常量池中,而是在堆中分配内存进行存储 - 【intern方法】
String ab4 = ab3.intern;
如果常量池中存在和ab3对象相同的字符串常量,则返回常量池中对应字符串常量的引用,否则添加该字符串常量到字符串常量并返回其引用
总结:String类以及其成员变量都是final修饰,字符串对象被创建后不可变,对该对象的任何操作都会重新生成一个新的对象
- StringBuilder 线程不安全
- StringBuffer 线程安全
总结:可变字符串类创建的字符串对象内容是可以被修改的



