美文网首页
装箱 VS 拆箱

装箱 VS 拆箱

作者: mysimplebook | 来源:发表于2019-12-05 18:36 被阅读0次

java中 的Boolean、Short、Integer、Long、Float、Double类被称为数值型基本类型的打包类。为什么叫做打包类呢?

因为我们有时候想让基本类型像对象一样操作(对象可以提供更多的信息),就需要使用它们来打包(wrap)java基本类型。这些类的主要目的就是提供对象实例作为壳,将基本类型打包在对象之中,这样就可以操作这个对象,就像是将基本类型当做对象操作。

       Java中这些包装类有8种,基础数据类型与它们对应的包装类见下图

基本类型的包装类的使用方法为使用new创建包装类,再传入相应的基本类型的数据,如

                        Integerintwrap = new Inter(data)

Java中基础数据类型与它们的包装类进行运算时,编译器会自动帮我们进行转换,转换过程对程序员是透明的,这就是装箱和拆箱。装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包装器类型转换为基本数据类型。

当基础类型与它们的包装类有如下几种情况时,编译器会自动帮我们进行装箱或拆箱。

Java中基础数据类型与它们的包装类进行运算时,编译器会自动帮我们进行转换,转换过程对程序员是透明的,这就是装箱和拆箱。装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包装器类型转换为基本数据类型。

当基础类型与它们的包装类有如下几种情况时,编译器会自动帮我们进行装箱或拆箱。

• 进行 “=”赋值操作,会进行装箱或拆箱操作,具体因左侧类型声明而异,如,

        Integer num1=99;

Integer num2=1;

        int total=num2;

执行上面那句代码的时候,系统为我们执行了:

Integer total = Integer.valueOf(99);

而valueOf源码为

public static Integer valueOf(int i) {

return  i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128];

}

其中,

private static final Integer[] SMALL_VALUES = new Integer[256];

它是一个静态的Integer数组对象,也就是说最终valueOf返回的都是一个Integer对象。对于Integer,在(-128,128]之间只有固定的256个值,所以为了避免多次创建对象,事先就创建好一个大小为256的Integer数组SMALL_VALUES,所以如果值在这个范围内,就可以直接返回我们事先创建好的对象就可以了,它被称为常量池。

实际上,Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。

而Double、Float的valueOf方法的实现是类似的。但它们每次都返回不同的对象。

public static Double valueOf(double d) {

    return new Double(d);

}

这里可以用instanceof是关键字判断一个对象是否是另一个对象的实例,如

System.out.println(num1 instanceof Integer);          //true

可见,装箱的过程会创建对应的对象,这个会消耗内存,所以装箱的过程会增加内存的消耗,影响性能。

执行下面那句代码的时候,系统为我们执行了:

int total = num1.intValue();

其中,intValue源码为

@Override

public int intValue() {

    return value;

}

• 进行+,-,*,/混合运算,会进行拆箱操作,如

System.out.println(num1+num2);    //100

System.out.println(num1+num2 instanceof  Integer); // error: unexpected type

• 进行>,<比较运算,会执行拆箱操作

System.out.println(num1>total);  //true

• 调用equals进行比较,会执行拆箱操作,使用“==”比较,会进行封箱操作

大多数程序设计语言中,使用“==”运算符来判断两个变量是否相等。在java中,使用“==”需要注意运算符两边的类型。

当==用于基本类型时,是比较两个变量存储的值是否相等。但在比较两个对象的时候,则是在比较两个引用变量是否引用的是同一个对象。因为“=”的意思是将某个变量名绑定到某个对象,而==是比较两个变量名是否绑定到同一对象。

如对于如下两行代码

        Integer num1=300;

       Integer num2=300;

300在转为Integer对象时会new一个对象出来。因为它们不在常量池中,所以是两个不同的对象

       System.out.println(num1==num2);    //false

而equals则是判断两个对象的值是否相等。

        System.out.println(num1.equals(num2));      //true

如果改写代码为

       Integer num1=100;

       Integer num2=100;

       因为100经包装后,放入常量池中,所以有

        System.out.println(num1==num2);     //true

       如果在java中创建对象显式使用关键字new创建对象,如

Integer a = new Inter(100)

Integer b = new Inter(100)

       我们看到该关键字,就知道建立了一个新对象,这时它们是两个不同的对象,因为它们不会存放在常量池中,

     System.out.println(num1==num2);// false

•    ArrayList,HashMap等集合类 添加基础类型数据时,执行装箱操作

相关文章

网友评论

      本文标题:装箱 VS 拆箱

      本文链接:https://www.haomeiwen.com/subject/wqqjgctx.html