判断两个Integer是否相等,使用==会产生的问题分析

        Integer a = 128;
        Integer b = 128;
        System.out.print(a==b); //false

        Integer c = 127;
        Integer d = 127;
        System.out.print(c==d); //true

==对于非基本类型来说,是判断两个引用是否指向同一个对象,或者说指向的地址是不是同一个地址。

那为什么数字是128的时候返回false,而数字是127的时候返回ture呢?
这种行为差异的原因是JVM维护Integer范围为-128到127 的对象的缓存。
因此,数字为128的时候(超出了127的范围),会创建新的对象。而数字为127的时候,返回的是同一个指向同一个对象的引用。

上面说到缓存口说无凭,来看源码:

public static Integer valueOf(inti) {    
    if(i >= -128 &&i <=IntegerCache.high)    
       //如果i在-128~high之间,就直接在缓存中取出i的Integer类型对象  
       return IntegerCache.cache[i + 128];    
    else  
       return new Integer(i); //否则就在堆内存中创建   
}    
    Integer c = new Integer(127);
    Integer d = Integer.valueOf(127);
    System.out.print(c==d); //false

这又是怎么回事呢?
其实咱们的 integer a = 127 等价于 Integer.valueOf(127)
这两种写法都是会去拿缓存的里对象的。
而new 的话,都是会直接创建对象的。
所以c是一个直接创建的对象,而d是从缓存里拿的对象,c和d指向的地址不相同,肯定==就会返回false了。

自动装箱拆箱机制:
如果在比较的过程中有对某个包装类型进行了+ - * / 等操作时,会自动的进行拆箱操作,最终会比较两端的数值大小。

当 “==”运算符的两个操作数都是 包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)。

Java使用自动装箱和拆箱机制,节省了常用数值的内存开销和创建对象的开销,提高了效率。通过上面的研究和测试,结论如下:

​ (1)Integer和 int之间可以进行各种比较;Integer对象将自动拆箱后与int值比较

​ (2)两个Integer对象之间也可以用>、<等符号比较大小;两个Integer对象都拆箱后,再比较大小

​ (3) 两个Integer对象最好不要用==比较。因为:-128~127范围(一般是这个范围)内是取缓存内对象用,所以相等,该范围外是两个不同对象引用比较,所以不等。

猜你喜欢

转载自blog.csdn.net/u011328417/article/details/81431556