(1)
Integer i = 156;
Integer j =156;
if(i == j)
System.out.println(true);
System.out.println(true);
(2)
Integer i1 = 126;
Integer j1 = 126;
if(i1 == j1)
System.out.println(true);
System.out.println(true);
上面将各输出什么结果?
(1)true
(2)true true
我们来分析一下原理:
对Integer对象,JVM会自动缓存-128~127范围内的值,所以所有在这个范围内的值相等的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);
}
因此,当使用Integer x = y进行声明时,当y的值在-128127范围内时,实际上获取的是常量缓存区的值,这时相等的Integer对象都会共用一块内存地址,而不会开辟多个内存地址;当y的值在-128127范围外时,不管值相不相等都会开辟多个内存地址,而在比较引用类型时,==比较的是引用的地址,因此无论如何结果都是false;需要注意的是,如果是Integer x = new Integer(y),这种方式,那么不管值相不相等都会开辟多个内存地址,而在比较引用类型时,==比较的是引用的地址,因此无论如何结果都是false;
案例:
package com.yzh.maven.main;
public class Test {
public static void main(String[] args) {
Integer i = 156;
Integer j =156;
if(i == j)
System.out.println(true);
System.out.println(true);
Integer i1 = 126;
Integer j1 = 126;
if(i1 == j1)
System.out.println(true);
System.out.println(true);
Integer i2 = 102;
int i3 = 102;
System.out.println(i2 == i3);
Integer i4 = 172;
int i5 = 172;
System.out.println(i4 == i5);
Integer i6 = 172;
Integer i7 = 172;
System.out.println(i6 == i7);//false
Integer i8 = new Integer(100);
Integer i9 = new Integer(100);
System.out.println(i8 == i9);//false
Integer i10 = new Integer(190);
Integer i11 = new Integer(190);
System.out.println(i10 == i11);//false
System.out.println(i8.hashCode() == i9.hashCode());//true,hashcode相同,对象不一定相同
/**
* public int hashCode() {
* return value;
* }
* private final int value;
* public Integer(int value) {
this.value = value;
}
*/
}
}
其实Integer与int类型的赋值与比较最关键的一点就是:这两个变量的类型不同。Integer是引用类型,int是原生数据类型。
我们分四种情况来讨论:
1) Integer与int类型的赋值
a. 把int类型赋值给Integer类型。此时,int类型变量的值会自动装箱成Integer类型,然后赋给Integer类型的引用,这里底层就是通过调用valueOf()这个方法来实现所谓的装箱的。
b. 把Integer类型赋值给int类型。此时,Integer类型变量的值会自动拆箱成int类型,然后赋给int类型的变量,这里底层则是通过调用intValue()方法来实现所谓的拆箱的。
2) Integer与int类型的比较
在这种方式中,Integer == int与int == Integer的效果是一样的,都会把Integer类型变量拆箱成int类型,然后进行比较,相等则返回true,否则返回false。同样,拆箱调用的还是intValue()方法。
3) Integer之间的比较
这个种方式是直接把两个引用的值(即是存储目标数据的那个地址)进行比较,无需再拆箱、装箱的过程。
例
Integer a1 = 160;
int a3 = 160;
System.out.println(a1++ == a3++);//true,会拆箱成int类型进行比较
Integer b1 = 150;
Integer b2 = 150;
Integer b3 = b1 + 1;
Integer b4 = b2 + 1;//还是Integer类型
System.out.println(b3 == b4);//flase