1.字面量+字面量
例:String s1 = "abc" + "def";
创建对象个数:1个-->常量池中:"abcdef"
原因:对于字符串常量 "abc" 和 "def" ,在进行拼接操作 "abc" + "def" 时,在编译期就会进行优化。Java编译器会识别出这是两个常量字符串的拼接,并在编译时直接将其计算为 "abcdef" ,然后将这个结果字符串放入字符串常量池中。整个过程只在常量池中创建了一个 "abcdef" 字符串对象。
2.字面量+对象+字面量
例:String s1 = "abc";
String s2 = "abc" + s1 + "def";
创建对象个数:3个-->常量池中:"abc"、"def"
堆中:"abcabcdef"
原因:String s1 = "abc";创建了一个String对象"abc",并将其放入常量池中;
String s2 = "abc" + s1 + "def"; "abc"对象在常量池中已经有了,直接将其拿出用即可;s1是引用地址,指向了 "abc" ,即 s1 = = "abc" 为true;创建了一个String对象 "def" 并将其放入常量池中;在堆中创建对象 "abcabcdef" ,因为s1是变量,当字符串拼接操作遇到字符串变量时,Java会创建一个新的String对象并放入堆中,而不是常量池中,这是因为Java不能确定这个拼接的结果在程序的其他地方是否会被修改(在编译期不能确定结果),所以不能放入常量池中。
3.new String("xx") + new String("xx")
例:String s = new String("abc") + new String("abc");
创建对象个数:4个-->常量池中:"abc"
堆中:3个
原因:JVM先在String池中创建一个String对象存储"abc";遇到new关键字则在堆中创建一个String对象存储"abc",其 char value[ ]指向了String池中的 char value[ ];第二个new关键字只在堆上创建了一个String对象存储"abc"(因为new操作符总是在堆上分配新的内存空间),因为String池中已经有 "abc" 了;最后进行字符串拼接操作,在堆上创建一个String对象 "abcabc"。
4.字面量 + new String("xx")
例:String s = "abc" + new String("def");
创建对象个数:4个-->常量池中:"abc"、"def"
堆中:2个
原因:JVM先在String池中创建两个String对象分别存储 "abc"、"def" ;遇到new关键字则在堆中创建一个String对象存储 "def",其char value[ ]指向了常量池中的 cahr value[ ];最后拼接在堆上创建一个String对象 "abcdef"
标签:abc,系列,String,创建对象,池中,new,def,常量 From: https://blog.csdn.net/weixin_63172268/article/details/143524256