java字符串的"+"操作分為2種:
1. 字面常量相加: String s1="a"+"b";
String s2= "a";
String s3="b";
2. String對象相加: String s4=s2+s3; 或 String s5=s2+"b";
先說結論:
1.加號"+"兩邊任意一邊是String對象而非字面常量時,都會在堆區new一個新的String對象出來,並且會檢查常量池是否有對應值的對象,如果沒有會在常量池創建一個對應值的新對象;有則引用該常量池對象;
2.如果"+"的兩邊都是字面常量,則會優先在字符串常量池中尋找相同的值,如果有則引用該對象,否則創建新的String對象並放入常量;
以下是推導出結論的數據和例子:
1 public static void main(String[] args) { 2 String s1="ab"; 3 String s2="a"+"b"; 4 String s3="a"; 5 String s4="b"; 6 String s5=s3+s4; 7 String s6="aba"; 8 String s7=s1+s3; 9 // false 10 System.out.println(s5==s2); 11 // true 12 System.out.println(s1==s2); 13 // 推測1, 字面常量會被存入String的常量池,而字面常量通過"+"拼接時會被編譯器優化為另一個字面常量,如"a"+"b",優化后就是"ab", 14 //因s1已經先聲明了,所以String常量池已經有"ab"了,故s2引用的s1是同一個常量池中的對象,所以 s1==s2結果確實為true 15 16 // 推測2,s5=s3+s4,s3與s4是2個String類型的對象, String對象+String對象的結果等於new 新的String對象,無論該String對象的值是否存儲在string常量池中都會在堆中新增一個 17 // 預估 s6==s7為fasle,結果fasle ,符合推測1。推測1通過 18 System.out.println(s6==s7); 19 20 // 擴展1: String字面常量+String對象了? 21 String s8="abc"; 22 String s9=s1+"c"; 23 // 結果:false, 推測3,只要 + 的任意一邊是String對象,則都會new 新的String對象 24 System.out.println(s8==s9); 25 String s10="a"+s4; 26 // 結果:false, 推測3通過 27 System.out.println(s1==s10); 28 29 // 擴展2: 如果常量池中已經存2個相同值的對象(1個由2個字面常量相加而創建 ,另一個由String對象"+"操作創建)時,再一次由字面常量相加時是否會創建新的String對象,還是復用原有對象?
// (實際上,常量池中不會存在相同值的對象,通過 "javap -verbose java類名" 可以查看驗證常量池的數據。 )
30 String s11="a"+"b"; 31 // 預估:true,結果:true, 32 System.out.println(s1==s11); 33 34 String s12=s3+"b"; 35 // 預估:false,結果:false 36 System.out.println(s1==s12); 37 43 44 }
以下是常量池的數據:

圖中紅線部分就是字符串常量池中的數據;
參考:
1. 如何查看java常量池:https://blog.csdn.net/u010741466/article/details/84920253
2. java字符串常量池:https://www.cnblogs.com/niew/p/9597379.html
