Java 的Integer、int与new Integer到底怎么回事?
***1:
当这个值大于等于-128并且小于等于127时使用了常量池,所以前两个地址是相等的,但是后两个超过了127,故不使用常量池
当值在-128到127中会进行自动的转型Integer.valueOf(int);
int a=2;
Integer b=2;
Integer c=2;
a==b; true
a==c;true
b==c;true
当值不在-128到127中
a==b;true
a==c;true
b==c;false
****2:
创建对象,装箱
int a=2;
Integer b=new Integer(b);
Integer c=new Integer(c);
a==b;true
a==c;true
b==c;false
先做一些总结,询问了些经验比较多的师傅,在这里表示感谢,然后自己总结下,今天的收获分享给大家:
1. int 和Integer在进行比较的时候,Integer会进行拆箱,转为int值与int进行比较。
2. Integer与Integer比较的时候,由于直接赋值的时候会进行自动的装箱,那么这里就需要注意两个问题,一个是-128<= x<=127的整数,将会直接缓存在IntegerCache中,那么当赋值在这个区间的时候,不会创建新的Integer对象,而是从缓存中获取已经创建好的Integer对象。二:当大于这个范围的时候,直接new Integer来创建Integer对象。
3. new Integer(1) 和Integer a = 1不同,前者会创建对象,存储在堆中,而后者因为在-128到127的范围内,不会创建新的对象,而是从IntegerCache中获取的。那么Integer a = 128, 大于该范围的话才会直接通过new Integer(128)创建对象,进行装箱。
实例分析
先看一个例子。
- public class Test {
- public static void main(String[] args) {
- Integer i = new Integer(128);
- Integer i2 = 128;
- System.out.println(i == i2);
- Integer i3 = new Integer(127);
- Integer i4 = 127;
- System.out.println(i3 == i4);
- Integer i5 = 128;
- Integer i6 = 128;
- System.out.println(i5 == i6);
- Integer i7 = 127;
- Integer i8 = 127;
- System.out.println(i7 == i8);
- }
- }
- false
- false
- false
- true
第一个情况:
- Integer i = new Integer(128);
- Integer i2 = 128;
i 是创建的一个Integer的对象,取值是128。
i2 是进行自动装箱的实例,因为这里超出了-128--127的范围,所以是创建了新的Integer对象。
那么i和i2都是Integer的对象咯。存储在堆中,分配的地址不同,在使用==进行判读的时候,由于双方都是对象,所以比较对象的地址是不是相同,这里的地址是不同的,因为new的时候会在堆中重新分配存储空间。
第二个情况:
- Integer i3 = new Integer(127);
- Integer i4 = 127;
i4 是进行自动装箱后生成的Integer的对象,其值-128<= i4 <= 127,所以在这里会与第一种情况有所不同,这个i4对象直接取缓存IntegerCache中的对应的对象,当然了也是对象。
那么i3和i4也都是对象咯,而且一个是缓存中的,一个自己new的,既然是对象那么==会比较其地址,因为都new出来的对象(一个是自己new出来的,一个是IntegerCache中new出来的对象),那么自然这两种情况下,在堆中分配的地址是不同的。
第三种情况:
- Integer i5 = 128;
- Integer i6 = 128;
i5是自动装箱产生的Integer的对象,但是其大小超过了范围:-128<=A <=127,那么,这里会直接自己创建该对象即:new Integer(128);
i6和i5类似的原理。
显然这两个对象都是new出来,在堆中的地址值是不同的,那么==的时候判读其地址是不是相等,也就不一样了。
第四种情况:
- Integer i7 = 127;
- Integer i8 = 127;
源码解析
下面看下,Integer中的装箱的代码
当不用new Integer的时候,构造方法会通过这个方法来构造对象并返回。那么你看if中的代码就知道了,i>=IntegerCache.low&&i<=IntegerCache.high的时候,从IntegerCache中获取的实例,否则,直接new Integer(i);
下面就是IntegerCache的代码,其中low就是-128,high是默认的127,不过可以进行设置。
通过静态代码块直接创建了256个Integer的对象,从-128到127之间。
所以在第四种情况中,取出来的时候,都是经过了上面的return IntegerCache.cache[i + (-IntegerCache.low)]得到的最终的对象,因为在IntegerCache中是创建好的,不会从新new了,所以地址值是一样的,也就是同一个对象,所以为true。
转载请注明出处:Java 的Integer、int与new Integer到底怎么回事?