前言
java中的数据类型分为基本数据类型和复杂数据类型.int是基本数据类型,Integer是复杂数据类型.所以int的默认值为0,而Integer的默认值为null,即Integer可以区分出未赋值和值为0的区别,int则无法表达出未赋值的情况。
java中为什么要引入Integer?
个人认为很多java api的调用包括方法的传旨或者范型的使用都是基于Object的,所以引入了Integer,引入了自动装箱与拆箱,这些方便api的调用.
java中的自动装箱与拆箱
自动装箱:
Integer i = 100;
相当于编译器自动为您作以下的语法编译:Integer i = Integer.valueOf(100);
换句话说,装箱就是jdk自己帮你完成了调用Integer.valueOf(100)。
Integer类的valueOf(int i)方法实现
/**
* Returns a <tt>Integer</tt> instance representing the specified
* <tt>int</tt> value.
* If a new <tt>Integer</tt> 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.
*
* @param i an <code>int</code> value.
* @return a <tt>Integer</tt> instance representing <tt>i</tt>.
* @since 1.5
*/
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
自动拆箱:
自动拆箱(unboxing),也就是将对象中的基本数据从对象中自动取出:
Integer i = 10; //装箱
int m = i; //拆箱,实际上执行了 int m = i.intValue();
下面的测试是针对int和Integer的区别分析
@Test
public void testInteger(){
//会把Integer自动拆箱为 int再去比,等同于Integer in=10;
Integer in=new Integer(10);
int i=10;
System.out.println(i==in);//true
Integer i1=new Integer(20);
Integer i2=20;
System.out.println(i1==i2);//false
Integer i3=new Integer(30);
Integer i4=new Integer(30);
System.out.println(i3==i4);//false
Integer i5=40;
Integer i6=40;
System.out.println(i5==i6);//true
System.out.println("================");
Integer i7=-127;
Integer i8=-127;
System.out.println(i7==i8);//true
Integer i9=127;
Integer i10=127;
System.out.println(i9==i10);//true
Integer i11=128;
Integer i12=128;
System.out.println(i11==i12);//false
Integer i13=-128;
Integer i14=-128;
System.out.println(i13==i14);//true
//Integer缓存区间[-128,127]
超出Integer的缓存范围,不从私有静态内部类IntegerCache的 数组cache中获得,而是通过new返回新对象
Integer i131=-129;
Integer i132=-129;
System.out.println(i131==i132);//false
Integer i15=250;
Integer i16=250;
System.out.println(i15==i16);//false
}
Integer源码片段:
/* @param i an <code>int</code> value.
* @return a <tt>Integer</tt> instance representing <tt>i</tt>.
* @since 1.5
*/
public static Integer valueOf(int i) {
//没有设置的话,IngegerCache.high 默认是127
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
对于–128到127(默认是127)之间的值,Integer.valueOf(int i) 返回的是缓存的Integer对象(并不是新建对象)
而其他值,执行Integer.valueOf(int i) 返回的是一个新建的 Integer对象
private static class IntegerCache {
static final int high;
static final Integer cache[];
static {
final int low = -128;
// high value may be configured by property
int h = 127;
if (integerCacheHighPropValue != null) {
// Use Long.decode here to avoid invoking methods that
// require Integer's autoboxing cache to be initialized
int i = Long.decode(integerCacheHighPropValue).intValue();
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - -low);
}
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() {}
}
看一下源码大家都会明白,对于-128到127之间的数,会进行缓存.
IntegerCache有静态成员变量cache,为一个拥有256个元素的数组。在IntegerCache中也对cache进行了初始化,即第i个元素是值为i-128的Integer对象。而-128至127是最常用的Integer对象,这样的做法也在很大程度上提高了性能.
结论
针对以上案例分析得出如下结论:
1)Integer与new Integer不会相等,他们的内存地址不一样
2)两个都是非new出来的Integer,如果数在-128到127之间,则是true,否则为false
3)两个都是new出来的,都为false
4)int和integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去做对比.