public static void main(String[] args) { String a = "a1"; String b = "a" + 1; System.out.println(a == b); }
public static void main(String[] args) {
String a = "ab";
String bb = "b";
String b = "a" + bb;
System.out.println(a == b);
}
public static void main(String[] args) {
String a = "ab";
final String bb = "b";
String b = "a" + bb;
System.out.println(a == b);
}
public static void main(String[] args) {
String a = "ab";
final String bb = getBB();
String b = "a" + bb;
System.out.println(a == b);
}
private static String getBB() {
return "b";
}
private static String a = "ab";
public static void main(String[] args) {
String s1 = "a";
String s2 = "b";
String s = s1 + s2;
System.out.println(s == a);
System.out.println(s.intern() == a);
}
private static String a = new String("ab");
public static void main(String[] args) {
String s1 = "a";
String s2 = "b";
String s = s1 + s2;
System.out.println(s == a);
System.out.println(s.intern() == a);
System.out.println(s.intern() == a.intern());
}
答案解析:
String對象的存儲?
String x = "abc"; String y = new String("abcd");
可以看出,x與y存在棧中娇斩,它們保存了相應(yīng)對象的引用。第一條語句沒有在堆中分配內(nèi)存孕索,而是將“abc”保存在常量池中甩牺。對于第二條語句嘲碱,同樣會在常量池中有一個“abcd”的字符串窖逗,當(dāng)new時址否,會拷貝一份該字符串存放到堆中,于是y指向了堆中的那個“abcd”字符串
1.當(dāng)兩個字符串字面值連接時(相加)碎紊,得到的新字符串依然是字符串字面值佑附,保存在常量池中
2.當(dāng)字符串字面值與String類型變量連接時,得到的新字符串不再保存在常量池中仗考,而是在堆中新建一個String對象來存放音同。很明顯常量池中要求的存放的是常量,有String類型變量當(dāng)然不能存在常量池中了秃嗜。字符串字面值與String類型常量連接瘟斜,得到的新字符串依然保存在常量池中。
3.final String bb = getBB();其實與final String bb = new String(“b”);是一樣的痪寻。也就是說return “b”會在堆中創(chuàng)建一個String對象保存”b”,雖然bb被定義成了final虽惭∠鹄啵可見并非定義為final的就保存在常量池中,很明顯此處bb常量引用的String對象保存在堆中芽唇,因為getBB()得到的String已經(jīng)保存在堆中了顾画,final的String引用并不會改變String已經(jīng)保存在堆中這個事實。
4.返回字符串對象的規(guī)范化表示形式匆笤。 一個初始為空的字符串池研侣,它由類 String 私有地維護。
當(dāng)調(diào)用 intern 方法時炮捧,如果池已經(jīng)包含一個等于此 String 對象的字符串(用 equals(Object) 方法確定)庶诡,則返回池中的字符串。否則咆课,將此 String 對象添加到池中末誓,并返回此 String 對象的引用。
它遵循以下規(guī)則:對于任意兩個字符串 s 和 t书蚪,當(dāng)且僅當(dāng) s.equals(t) 為 true 時喇澡,s.intern() == t.intern() 才為 true。
所有字面值字符串和字符串賦值常量表達式都使用 intern 方法進行操作殊校。