其实Integer与int类型的赋值与比较最关键的一点就是:这两个变量的类型不同。Integer是引用类型,int是原生数据类型。
我们分四种情况来讨论:
1) Integer与int类型的赋值
a.把Integer类型赋值给int类型。此时,Integer类型变量的值会自动拆箱成int类型,然后赋给int类型的变量,这里底层则是通过调用intValue()方法来实现所谓的拆箱的。
b.把int类型赋值给Integer类型。此时,int类型变量的值会自动装箱成Integer类型,然后赋给Integer类型的引用,这里底层就是通过调用valueOf()这个方法来实现所谓的装箱的。
2) Integer与int类型的比较
这里就无所谓是谁与谁比较了,Integer == int与int ==
Integer的效果是一样的,都会把Integer类型变量拆箱成int类型,然后进行比较,相等则返回true,否则返回false。同样,拆箱调用
的还是intValue()方法。
3) Integer之间的比较
这个就相对简单了,直接把两个引用的值(即是存储目标数据的那个地址)进行比较就行了,不用再拆箱、装箱什么的。
4) int之间的比较
这个也一样,直接把两个变量的值进行比较。
值得注意的是:对Integer对象,JVM会自动缓存-128~127范围内的值,所以所有在这个范围内的值相等的Integer对象都会共用一块内
存,而不会开辟多个;超出这个范围内的值对应的Integer对象有多少个就开辟多少个内存。底层代码如下:
- <span style="font-size:24px;"> 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);
- }
- </span>
测试代码如下:
- <span style="font-size:24px;">public class IntegerAndIntTest
- {
- public static void main(String[] args) throws Exception
- {
- Integer a = 127, b = 128;
- int c = 128;
- //自动装箱,这里会调用Integer中的valueOf方法把c装箱成Integer类型
- a = c;
- //这里比较的是两个对象的地址,显然不等
- System.out.println(a == b);
- //这里会调用Integer的intValue方法获得Integer对象a指向的栈地址中存的值再与c进行值比较,
- //而不是把c装箱成Integer类型进行地址比较
- System.out.println(a == c);
- //同上,也是获得a指向的栈地址中存的值
- System.out.println(c == a);
- /**
- * 总结:只有在赋值(=)的时候才会出现装箱和拆箱两种情况,
- * 在比较(==)的时候只会出现一种情况,那就是拆箱,而不会出现装箱的情况
- */
- System.out.println("----------------------------------");
- Integer i1 = 127;
- Integer i2 = 127;
- System.err.println(i1 == i2);
- i1 = 128;
- i2 = 128;
- System.err.println(i1 == i2);
- /**
- * 总结:JVM会自动缓存-128~127范围内的值,所以所有在这个范围内的值相等的Integer对象都会共用一块内存,而不会开辟多个;
- * 超出这个范围内的值对应的Integer对象有多少个就开辟多少个内存,这样做是为了节省内存消耗。
- */
- }
- }
- </span>