String 类的实例是不可改变的,所以你一旦创建了 String 对象,那它的值就无法改变了
String 类是不可改变的解析,例如:
String s = "Google";
System.out.println("s = " + s); s = "Runoob";
System.out.println("s = " + s);
输出结果为:
Runoob
从结果上看是改变了,但为什么门说String对象是不可变的呢?
原因在于实例中的 s 只是一个 String 对象的引用,并不是对象本身,当执行 s = "Runoob"; 创建了一个新的对象 "Runoob",而原来的 "Google" 还存在于内存中。
所以变化的是变量中保存的引用,而不是对象本身。对象本身是不可变的
关于 String 为啥是不可改变的
这里可以根据 jdk 的源码来分析。
字符串实际上就是一个 char 数组,并且内部就是封装了一个 char 数组。
并且这里 char 数组是被 final 修饰的:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
并且 String 中的所有的方法,都是对于 char 数组的改变,只要是对它的改变,方法内部都是返回一个新的 String 实例
字符串的连接, 有两种方法,concat() 和 +
String s1 = "abc";
String s2 = "def";
String s3 = s1.concat(s2); //字符串变量的连接
String s4 = "字符串常量1".concat("字符串常量2"); //字符串常量的连接
String s5 = s1 + s2; //字符串变量的连接
String s6 = "字符串常量1" + "字符串常量2"; //字符串常量的连接
字符串的+操作其本质是new了StringBuilder对象进行append操作,拼接后调用toString()返回String对象
两个或者两个以上的字符串常量相加,在预编译的时候“+”会被优化,相当于把两个或者两个以上字符串常量自动合成一个字符串常量
字符串常量相加,不会用到StringBuilder对象,有一点要注意的是:字符串常量和字符串是不同的概念,字符串常量储存于方法区,而字符串储存于堆(heap)。
String s1 = "Programming";
String s2 = new String("Programming");
String s3 = "Program";
String s4 = "ming";
String s5 = "Program" + "ming";
String s6 = s3 + s4;
System.out.println(s1 == s2); //false
System.out.println(s1 == s5); //true
System.out.println(s1 == s6); //false
字符串常量池
https://segmentfault.com/a/1190000009888357?utm_source=tag-newest