String属于引用类型,创建的对象放在堆上,引用放在栈上
String c = "aaa";
在堆上分配一片内存,创建对象保存数据aaa,而c属于在创建在栈上的引用,指向保存数据堆的位置
这时再添加一个String c=”bbb”;
这时堆上开辟一个新内存,保存数据bbb,然后c指向bbb
然后再String d=”bbb”; 因为bbb已经存在,并且被保存在了字符串常量池里面,所以
d就不用判断了一下,所要创建的对象存在,不用再创建了,直接引用d指向bbb就行了
这时c与d指的是同一个对象
创建字符串有两种方式
1.使用new运算符
String str =
new
String(
"Hello"
);
2.使用字符串常量或者常量表达式 这个创建字符串的方式才使用字符串常量池
String str=
"Hello"
;
//(字符串常量) 或者
String str=
"Hel"
+
"lo"
;
//(字符串常量表达式)
String a=
"Hello"
;
String d=
"Hel"
;
String str=
d+”lo”
; 这里a==str false
对于这种类型的拼接,如果d在编译器可以确定值结果为true。否则为false,比如final String d=”Hel”
上面看完了图理解了字符串的拼接以及为什么说String不可变 从底层看一下不可变的原因
首先设置了private访问权限,外部无法直接访问,接着加上final无法被继承,并且没有提供setValue的公共方法,所以String对象建立后无法改变
其中substring, replace, replaceAll这样方法可以修改String对象的值,源码中修改方式是新建String一个对象,然后返回
接着把新的对象重新赋值给 引用,所以也是没有改变String对象
比如
String dString="12645";
String eString=dString.replace('1','3');
这时eString输出32645,而dString仍旧不变,
所以如果只dString.replace('1','3');这样,但是没有将新建的对象赋值给引用是无法输出32645的,因为dString不改变