您的位置:首页 > 其它

Integer与Int小谈

2015-11-29 23:16 183 查看
       Integer与Int是包装类与基本类型的关系,能够互相自动拆装箱;两者一起参与运算符运算的时候,往往都拆箱为基本数据类型运算。这些都是较为常见的知识了。

       对于拆箱过程,其实就是Integer内部调用了intValue()函数,因此,只要Integer对象不为空,则能够返回int值;若为空,则报空指针异常。

       对于装箱过程,其实其中有点小花头需要注意:

       对于如下代码:

//-128-127
Integer i1 = 127;
Integer j1 = 127;
System.out.print(i1==j1);//true

Integer i2 = 128;
Integer j2= 128;
System.out.print(i2==j2);//false

        Integer其实也是和String一样,不可变类型,一旦定义了Integer a = 1,就不能改变,如果i++其实就等于Integer a = 2或者说a = Integer.valueOf(a.intValue()+1);

      可以看到,凡是在-128-127范围内,两个Integer由装箱而成的对象指向同一个对象;而此范围外的数则指向不同对象,何由?

      其实,装箱过程,是由Integer类内部的函数Integer valueOf(int i)来完成的;打开源码 :      

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);
}
        可以看到,当在高低范围内,基本类型int返回的是IntegerCache中的cache数组中的值;超出该范围外,返回的是new Integer(i),即重新开开辟堆空间;

      我们再打开IntegerCache源码:

private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];

static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
int i = parseInt(integerCacheHighPropValue);
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() {}
}
      首先看到,cache[]数组其实就是Integer类型;其次,high与low被定义为127与-128;然后该类中的静态代码块在类加载的时候就初始化了该cache数组,使得cache[]内已经包含了从-128到127的所有整数;

     因此可见,凡是通过装箱而来,即通过valueOf()函数生成的Integer对象,且值在-128-127范围内的数,相同的值都指向同一个对象,即cache[]数组中的对象;超出该值范围的装箱,都是通过valueOf()中的new Integer()重新开辟的堆空间,指向不同对象。

     PS:本文以Integer和int为例,对于其他基本类型,如Short,Long都有相同规律,对于Byte自身范围本身就在-128到127之间;但是对于Float和Double,没有用到常量池技术,因此内部也没有相应cache数组,其每一个对象都是新的。

     注意:对于如下:

int i = 128;
Integer j = 128;
System.out.print(i==j);//true
     基本类型与封装类混合参与比较,都是转化为基本类型进行比较,因此都是在栈中比较值,因此这里相等。

        

        
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: