【Java】Java代碼經典錯誤清單

一、String 對比 == 和 equals,具體描述如下

 "=="操作符的作用
1)用於基本數據類型的比較,如下:

byte(字節) 8 -128 - 127 0
shot(短整型) 16 -32768 - 32768 0
int(整型) 32 -2147483648-2147483648 0
long(長整型) 64 -9233372036854477808-9233372036854477808 0 
float(浮點型) 32 -3.40292347E+38-3.40292347E+38 0.0f
double(雙精度)	64 -1.79769313486231570E+308-1.79769313486231570E+308 0.0d
char(字符型) 16 ‘ \u0000 - u\ffff ’ ‘\u0000 ’
boolean(布爾型) 1 true/false false
2)判斷引用是否指向堆內存的同一塊地址。
equals所在位置:
在Object類當中,而Object是所有類的父類,包含在jdk裏面,但並不適合絕大多數場景,通常需要重寫

public boolean equals(Object obj) {
        return (this == obj);
    }
equals的作用:

用於判斷兩個變量是否是對同一個對象的引用,即堆中的內容是否相同,返回值爲布爾類型


二、Long 對比  == 和 equals,具體描述如下

Long相對來講是一個比較特殊的,先說下面的例子:

例子1:

/**
     * <一句話功能簡述> <功能詳細描述>
     * @author xutianlong
     * @param args
     * @see [類、類#方法、類#成員]
     */
    public static void main(String[] args)
    {
        Long long1 = 128L;
        Long long2 = 128L;
        if (long1 == long2)
        {
            System.out.println("true");
        }
        else
        {
            System.out.println("false");
        }

        if (long1.equals(long2))
        {
            System.out.println("true");
        }
        else
        {
            System.out.println("false");
        }

    }

輸出:false 和true


例子2:

 /**
     * <一句話功能簡述> <功能詳細描述>
     * @author xutianlong
     * @param args
     * @see [類、類#方法、類#成員]
     */
    public static void main(String[] args)
    {
        Long long1 = 1L;
        Long long2 = 1L;
        if (long1 == long2)
        {
            System.out.println("true");
        }
        else
        {
            System.out.println("false");
        }

        if (long1.equals(long2))
        {
            System.out.println("true");
        }
        else
        {
            System.out.println("false");
        }

    }

輸出:true和true


可能很多人覺得這是一件很神奇的事,其實不然,這個需要讀JDK的源碼才能知道原因,找到源碼

Long的裏面有一個私有的靜態內部類,實現如下:

  private static class LongCache {
        private LongCache(){}

        static final Long cache[] = new Long[-(-128) + 127 + 1];

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Long(i - 128);
        }
    }
再看他怎麼使用的:

 /**
     * Returns a {@code Long} instance representing the specified
     * {@code long} value.
     * If a new {@code Long} instance is not required, this method
     * should generally be used in preference to the constructor
     * {@link #Long(long)}, as this method is likely to yield
     * significantly better space and time performance by caching
     * frequently requested values.
     *
     * Note that unlike the {@linkplain Integer#valueOf(int)
     * corresponding method} in the {@code Integer} class, this method
     * is <em>not</em> required to cache values within a particular
     * range.
     *
     * @param  l a long value.
     * @return a {@code Long} instance representing {@code l}.
     * @since  1.5
     */
    public static Long valueOf(long l) {
        final int offset = 128;
        if (l >= -128 && l <= 127) { // will cache
            return LongCache.cache[(int)l + offset];
        }
        return new Long(l);
    }

顯而易見,-128到127直接的值都放在cache裏,不會創建新的對象,所以==比較的時候,結果是正確的,
當超過這個範圍,會創建的新對象,所以不會相等

三、Integer類型也是同理與Long類型,可以查看到Integer實現的時候也是存在IntegerCache,如下:

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) -1);
            }
            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() {}
    }

 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);
    }


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