深入理解Java之装箱与拆箱

作者 |衍方
来源 | urlify.cn/yqaANf
一、Java数据类型1、在说装箱与拆箱之前 , 先说一下Java的基本数据类型 , Java从数据类型上可以划分为值类型与引用类型 , 值类型是四类八种 , 分别是:

  • 整数型:byte? , short? , int? , long
  • 浮点型:?oat , double
  • 字符型:char
  • 布尔型:boolean
数据类型内存默认值包装类byte8位0Byteshort16位0shortint32位0Integerlong64位0L或0lLongfloat32位0.0F或0.0fFloatdouble64位0.0D或0.0dDoublechar16位\u0000Characterboolean8位flaseBoolean
【深入理解Java之装箱与拆箱】2、引用类型:
  • 数组
  • 类(class)
  • 接口(Interface)
  • 枚举(enum)

深入理解Java之装箱与拆箱文章插图
3、值类型与引用类型的区别
  1. 从概念方面上来说:
  2. 值类型:变量名指向具体的值
  3. 引用类型:变量名指向数据对象的内存地址
  4. 从内存构建方面上来说:
  5. 值类型:变量在声明之后 , Java就会立刻分配给它内存空间
  6. 引用类型:它以特殊的方式(类似C指针)指向对象实体 , 这类变量声明时不会分配内存 , 只是存储
  7. 从使用方面上来说:
  8. 值类型:使用时需要赋具体值 , 判断时用 ” == “号
  9. 引用类型:使用时可以赋null , 判断时使用 equals 方法
二、Java数据类型转换1、自动转换
  • 定义:程序在执行过程中“悄然”进行的转换 , 不需要用户提前声明 , 一般是从位数低的类型向位数高的类型转换
  • 优先关系:按从低到高的顺序转换 。 不同类型数据间的优先关系如下:
    • 低--------------------------------------------->高
    • byte,short,char-> int -> long -> float -> double
  • 转换规则:运算中 , 不同类型的数据先转化为同一类型 , 然后进行运算操作数1类型操作数2类型转换后的类型byte、short、charintintbyte、short、char、intlonglongbyte、short、char、int、longfloatfloatbyte、short、char、int、long、floatdoubledouble
2、强制转换
  • 定义:强制类型转换则必须在代码中声明 , 转换顺序不受限制
  • 格式:在需要转型的数据前加上“( )” , 然后在括号内加入需要转化的数据类型
  • 结果:精度可能会丢失 , 也可能更加精确
  • int x;double y;x = (int)3.14 + (int)5.20 //精度丢失y = (double)x + (double)8 //精度提升输出:x = 8;y = 16.0
三、Java之装箱与拆箱1、包装类
  • Java是面向对象语言 , 号称万事万物皆对象 , 因此 , 8种基本数据类型有了对应的类 , 这就是包装类
2、什么是装箱与拆箱
  • 装箱:将值类型装换成引用类型的过程
  • 拆箱:将引用类型转换成值类型的过程
  • 自动装箱:
  • int x = 3;Integer y = x; //int --> Integer , Integer y = x <==> Integer y = Integer.valueOf(x)
  • 自动拆箱:
  • Integer x = new Integer(5);int y = x; //Integer --> int , int y = x <==> int y = x.intValue()
3、装箱和拆箱是如何实现的
  • 装箱过程是通过调用包装器的valueOf方法实现的
  • 拆箱过程是通过调用包装器的 xxxValue方法实现的 。 (xxx代表对应的基本数据类型)
4、注意点:
  1. 大量使用自动拆装箱会使性能降低 , 还会造成大量的内存消耗
  2. 在重载方法中 , 可能出现问题List list = new ArrayList<>();Integer x,y,z;x = 1;y = 2;z = 4;list.add(x);list.add(y);list.add(z);list.remove(2);

深入理解Java之装箱与拆箱文章插图
在上面这段代码中ArrayList.remove方法有两个重载方法 , 那么list.remove(2)是调用了哪个方法 , remove掉的是值为2的对象 , 还是remove了index为2 , 值为4的那个对象呢?
在这种情况下 , 编译器不会进行自动拆装箱 , 所以调用的是remove(int index),index为2值为4的这个Integer对象会被remove.
如果要调用 remove(Object o)的方法 , 应该这么写 list.remove(y)
  1. 缓存值问题