燒腦的java字符串比較(字符串常量池、指向堆、指向字符串常量池)--jdk1.8

本文是在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類型
}

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章