Integer的比較==和String的比較==總結


一、序言

  今天發現了一個很有趣的問題,在群里和朋友們討論的也比較激烈,我現在給大家闡述一下問題。

二、發現問題

  上代碼。。。

package com.hzwealth.test.question;

public class IntegerTest {
    public static void main(String[] args) {
        //Integer
        Integer a=10,b=10,c=150,d=150;
        System.out.println(a==b);   
        System.out.println(c==d);
        System.out.println(a.equals(b));
        System.out.println(c.equals(d));
        //String
        String str=new String("AB");
        String str1 ="A";
        String str2 = str1+"B";
        String str3="AB";
        System.out.println(str==str3);
        System.out.println(str==str2);
        System.out.println(str2==str3);
    }
}

三、解決問題

  1、Integer的問題,首先我們先看上面代碼的 a==b會輸出什么呢,答案是true,這個毋庸置疑,但是c==d會輸出什么呢,答案是false,為什么呢?

    (1)Integer是基本數據類型的int的引用類型,官方語言叫做裝箱類型,我們來看一下Integer的源碼

//Integer的取值
public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low));
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }

        private IntegerCache() {}
    }

  從源碼我們可以看出,Integer的值為-128-127之間的時候就會自動的從Integer的緩存(IntegerCache)中去取,如果超過這個范圍就會新建一個Integer的對象。

  所以a==b(a=10,b=10)為true,c==d(c=150,d=150)為false。

 2、我們來看一下String的這個問題

  (1)str==str3 為false,因為,str新建了一個對象,str3是常量池中的對象,所以這兩個為false。

  (2)str2==str3,這個解釋引用我群友  成都-119-EbranHan-Java 的解釋:

   new 了一個 StringBuilder,然后調用了append方法,對應的就是:String str2 = str1+"B";

  這里還提到了字面量和引用,String str3="AB",這就是字面量,而引用就是,String str=new String("AB");我們自己定義的。

   字面量 jvm 優化過,直接就扔到常量池去了。

  下面是StringBuilder的toString方法,這里也是新建了一個String方法

 

    綜上所述,str2==str3也為false。

  補充:這里的“+”不是用的String 的concat的方法,而是用的是StringBuilder來寫的。而且,就算是用concat的方法也是new了一個String的對象。下面是concat的源碼:

public String concat(String str) {
        int otherLen = str.length();
        if (otherLen == 0) {
            return this;
        }
        int len = value.length;
        char buf[] = Arrays.copyOf(value, len + otherLen);
        str.getChars(buf, len);
        return new String(buf, true);
    }

  (3)str==str2,這個也毋庸置疑的為false了,因為str是new出來的String對象,str2也是相當於new出來的一個對象。所以為false。

四、評語

  以上是我根據自己查閱資料以及和群友的交流下寫出的總結,如果有不正確的地方,還望大牛指正!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM