java自动装箱和拆箱

序. java基本类型介绍

java中,基本数据类型一共有8种,详细信息如下表:

类型 大小 范围 默认值
byte 8 -128 - 127 0
short 16 -32768 - 32768 0
int 32 -2147483648-2147483648 0
long 64 -9233372036854477808-9233372036854477808 0
float 32 -3.40292347E+38-3.40292347E+38 0.0f
double 64 -1.79769313486231570E+308-1.79769313486231570E+308 0.0d
char 16 \u0000 - u\ffff \u0000
boolean 16 true/false false

1.什么是自动拆箱与自动装箱

自动装箱:把基本类型用它们对应的包装类包装起来,使它们具有对象的特质,可以调用所对应的包装类所定义的方法

自动拆箱:跟自动装箱的方向相反,将Integer及Double这样的包装类的对象重新简化为基本类型的数据。

p.s.所谓自动,就是说这个过程并不需要程序员去完成,而是jvm自动完成的,jvm会在编译期根据语法决定是否进行装箱和拆箱动作。 
另外,自动拆箱与自动装箱的jdk1.5才引入的新特性,所以如果你的jdk版本低于1.5的话,是不可以这样写的。

2.为什么会有自动拆箱与自动装箱

为什么java要提供这样一个功能呢?我的理解是这样的: 
1.因为懒。假如没有自动拆箱与自动装箱,那么我们的代码是这样的:

    Integer i = new Integer(2);//假如需要一个integer的对象i,值为2
    int b=i.intValue();//又需要一个int型的值,大小与i相等
  • 1
  • 2

但是,有了自动拆箱与装箱,我们就可以这么写:

        Integer i = 2;
        int b = i;

2.自动装箱的过程其实可以起到节约内存的作用。我们先看一个例子:

        Integer a = 1;
        Integer b = 1;
        Integer c = 144;
        Integer d = 144;
        Integer a1 = new Integer(1);
        Integer b1 = new Integer(1);
        System.out.println(a == b);         //true
        System.out.println(a.equals(b));    //true
        System.out.println(a1 == b1);       //false
        System.out.println(a1.equals(b1));  //true
        System.out.println(c == d);         //false
        System.out.println(c.equals(d));    //true

是不是很奇怪,为什么第7行为true而第12行为false呢?这是因为,在自动装箱时对于值从–128到127之间的值,它们被装箱为Integer对象后,会存在内存中被重用,始终只存在一个对象 。而如果超过了从–128到127之间的值,被装箱后的Integer对象并不会被重用,即相当于每次装箱时都新建一个 Integer对象。

那么,为什么要这么设计呢?一般来说,小数字的使用频率很高,将小数字保存起来,让其始终仅有一个对象可以节约内存,提高效率。


3.什么是自动拆箱与自动装箱

自动装箱有一个问题,那就是在一个循环中进行自动装箱操作的情况,如下面的例子就会创建多余的对象,影响程序的性能。

Integer sum = 0 ;
  for ( int i= 1000 ; i< 5000 ; i++){
    sum+=i;
}

上面的代码sum+=i可以看成sum = sum + i,但是+这个操作符不适用于Integer对象,首先sum进行自动拆箱操作,进行数值相加操作,最后发生自动装箱操作转换成Integer对象。其内部变化如下

sum = sum.intValue() + i;
Integer sum = new Integer(result);

由于我们这里声明的sum为Integer类型,在上面的循环中会创建将近4000个无用的Integer对象,在这样庞大的循环中,会降低程序的性能并且加重了垃圾回收的工作量。因此在我们编程时,需要注意到这一点,正确地声明变量类型,避免因为自动装箱引起的性能问题。


4.注意事项

另一个需要避免的问题就是混乱使用对象和原始数据值,一个具体的例子就是当我们在一个原始数据值与一个对象进行比较时,如果这个对象没有进行初始化或者为Null,在自动拆箱过程中obj.xxxValue,会抛出NullPointerException,如下面的代码

private static Integer count;
 
//NullPointerException on unboxing
if ( count <= 0 ){
   System.out.println( "Count is not started yet" );
}




你可能感兴趣的:(java)