java中你所不知道的'=='

再谈这个问题之前,我们先聊一聊java的8大原始数据类型:

(1)boolean——1 bit——Boolean

 

(2)byte——1 byte——Byte

(3)short——2 bytes——Short

(4)int——4 bytes——Integer

(5)long——8 bytes——Long

(6)float——4 bytes——Float

(7)double——8 bytes——Double

(8)char——2 bytes——Character

  "=="判断的是两个对象的内存地址是否一样,适用于原始数据类型和枚举类型(它们的变量存储的是值本身,而引用类型变量存储的是引用);equals是Object类的方法,Object对它的实现是比较内存地址,我们可以重写这个方法来自定义“相等”这个概念。比如类库中的String、Date等类就对这个方法进行了重写。

    综上,对于枚举类型和原始数据类型的相等性比较,应该使用"==";对于引用类型的相等性比较,应该使用equals方法。

引用类型:

(1)类calss

 (2)接口interface

(3)数组array

看到这里你们明白了吧?为什么int 要用==,而string却用equals。然后写到这里你以为就完了吗?其实才刚刚开始,前面这些只是小菜,重头戏在后面呢!

笔者经验:

有一次做android handler消息传递开发用Interger来比较两个数是不是一样,经过多次测试出现了下面的结果:

Interger i=100;

interger j=100;

i==j返回true;

然而当笔者这样写的时候,奇怪的事情发生了:

 

Interger i=1000;

interger j=1000;

i==j返回false;

各种懵逼啊!各种找bug啊!就是找不到,最后查Interger源码后知道了大概的原因:

 

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

    /**
     * Returns an {@code Integer} instance representing the specified
     * {@code int} value.  If a new {@code Integer} instance is not
     * required, this method should generally be used in preference to
     * the constructor {@link #Integer(int)}, as this method is likely
     * to yield significantly better space and time performance by
     * caching frequently requested values.
     *
     * This method will always cache values in the range -128 to 127,
     * inclusive, and may cache other values outside of this range.
     *
     * @param  i an {@code int} value.
     * @return an {@code Integer} instance representing {@code i}.
     * @since  1.5
     */
    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);
    }
通过这一段代码及注释,笔者猜测就是只有(-128-127)的interger才会返回true。接下来笔者就去寻找度娘了,一查还真是这样。原来在这个范围的数据是存在缓冲区的,并不会new出新的interger对象,所以==比较内存地址才会相等。顺便提一下:Double Float 没有缓冲区,也就是说这两个东西==不可能相等。其它的原始数据类型缓冲区都是(-128-127)。通过这个例子看出来了,引用类型的数据比较还是用equals比较好(顺便补充一个知识点:两个对象的equals相等,则hashcode相等,反之不成立)