本文是在jdk1.8的基礎上解析的。
在JDK1.8中
調用 intern() 該方法:
如果常量池中 有 一個和當前對象相等 (用equals比較) 的字符串, 則返回常量池中的字符串 ;
否則把改字符串放到常量池中,並返回 該字符串的引用 .
一、實例解析1
String str1=new String("he")+new String("llo"); // 在堆中產生三個對象,str1 只指向合併後生成的那個"hello"對象;
String str2="hello"; // 在常量池中找,沒有“hello”,所以在常量池中生成一個此常量對象,str2指向此對象,str2是常量對象的引用。
str1.intern(); // 在常量池中找,已經存在“hello”這個常量對象,故不生成常量引用.str1仍然指向堆中“hello”
System.out.println(str1==str2); // false // 兩個對象的地址不一樣,故false
String str1=new String("he")+new String("llo"); // 在堆中產生三個對象,string只指向合併後生成的那個"hello"對象;
str1.intern(); // 在常量池中找,沒有“hello”這個常量對象,所以把字符串放到常量池並返回這個常量字符串的引用,和堆中那個對象的地址相同
String str2="hello"; // 常量池中已經存在這個常量對象的引用,所以str2指向這個引用,所以str2也指向str1對象
System.out.println(str1==str2);// true // 地址一樣,內容一樣,所以true
public static void main(String[] args) { String str1 = new String("1"); //首先此行代碼創建了兩個對象(如果常量池事先沒有的話),在執行前會在常量池中創建一個"1"的對象引用,然後執行該行代碼時 new 一個"1"的對象存放在堆區中;然後str1指向堆區中的對象; str1.intern(); //因爲常量池中已經有常量“1”,故不會生成引用(即不改變str1的指向,str1仍然指向堆中對象)。 String str2 = "1"; // str2 是常量池中“1”的引用。故str1和str2指向不同 System.out.println(str1 == str2); //結果是 false }
public static void main(String[] args) { String str1 = "aaa"; String str2 = "bbb"; String str3 = "aaabbb"; String str4 = str1 + str2; String str5 = "aaa" + "bbb"; System.out.println(str3 == str4); // false String ss = str4.intern(); //如果常量池中 有 一個和當前對象相等 (用equals比較) 的字符串, 則返回常量池中的字符串,即使str4指向常量池中字符串的引用 System.out.println(str3 == ss); // true System.out.println(str3 == str5);// true }
public static void main(String[] args) { Integer a = 1; Integer b = 2; Integer c = 3; Integer d = 3; Integer e = 321; Integer f = 321; Long g = 3L; System.out.println(c == d); //true System.out.println(e == f); //false System.out.println(c == (a + b));//true System.out.println(c.equals(a+b));//true System.out.println(g == (a + b));//true //包裝類的“==”運行符在不遇到算術運算的情況下不會自動拆箱, // 以及他們的equals()方法不處理數據類型的關係, // 通俗的講也就是 “==”兩邊如果有算術運算, // 那麼自動拆箱和進行數據類型轉換處理,比較的是數值等不等。 System.out.println(g.equals(a + b));//false // Long的equals方法會先判斷是否是Long類型 }