深入理解Java之装箱与拆箱
作者 |衍方
来源 | urlify.cn/yqaANf
一、Java数据类型1、在说装箱与拆箱之前 , 先说一下Java的基本数据类型 , Java从数据类型上可以划分为值类型与引用类型 , 值类型是四类八种 , 分别是:
- 整数型:byte? , short? , int? , long
- 浮点型:?oat , double
- 字符型:char
- 布尔型:boolean
【深入理解Java之装箱与拆箱】2、引用类型:
- 数组
- 类(class)
- 接口(Interface)
- 枚举(enum)
文章插图
3、值类型与引用类型的区别
- 从概念方面上来说:
- 值类型:变量名指向具体的值
- 引用类型:变量名指向数据对象的内存地址
- 从内存构建方面上来说:
- 值类型:变量在声明之后 , Java就会立刻分配给它内存空间
- 引用类型:它以特殊的方式(类似C指针)指向对象实体 , 这类变量声明时不会分配内存 , 只是存储
- 从使用方面上来说:
- 值类型:使用时需要赋具体值 , 判断时用 ” == “号
- 引用类型:使用时可以赋null , 判断时使用 equals 方法
- 定义:程序在执行过程中“悄然”进行的转换 , 不需要用户提前声明 , 一般是从位数低的类型向位数高的类型转换
- 优先关系:按从低到高的顺序转换 。 不同类型数据间的优先关系如下:
- 低--------------------------------------------->高
- byte,short,char-> int -> long -> float -> double
- 转换规则:运算中 , 不同类型的数据先转化为同一类型 , 然后进行运算操作数1类型操作数2类型转换后的类型byte、short、charintintbyte、short、char、intlonglongbyte、short、char、int、longfloatfloatbyte、short、char、int、long、floatdoubledouble
- 定义:强制类型转换则必须在代码中声明 , 转换顺序不受限制
- 格式:在需要转型的数据前加上“( )” , 然后在括号内加入需要转化的数据类型
- 结果:精度可能会丢失 , 也可能更加精确
- int x;double y;x = (int)3.14 + (int)5.20 //精度丢失y = (double)x + (double)8 //精度提升输出:x = 8;y = 16.0
- Java是面向对象语言 , 号称万事万物皆对象 , 因此 , 8种基本数据类型有了对应的类 , 这就是包装类
- 装箱:将值类型装换成引用类型的过程
- 拆箱:将引用类型转换成值类型的过程
- 自动装箱:
- 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()
- 装箱过程是通过调用包装器的valueOf方法实现的
- 拆箱过程是通过调用包装器的 xxxValue方法实现的 。 (xxx代表对应的基本数据类型)
- 大量使用自动拆装箱会使性能降低 , 还会造成大量的内存消耗
- 在重载方法中 , 可能出现问题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);
文章插图
在上面这段代码中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)
- 缓存值问题
- 案例解析:Integer i1 = 100;Integer i2 = 100;Integer i3 = 200;Integer i4 = 200;System.out.println(i1==i2);System.out.println(i3==i4);Output: true false
- 观察源码:Intteger.valueOf方法public static Integer valueOf(int i) {if (i >= IntegerCache.low--tt-darkmode-color: #E6C07B;">return IntegerCache.cache[i + (-IntegerCache.low)];return 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 = http://kandian.youth.cn/index/sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low;for(int k = 0; k
- 现状|程序员现状揭秘:平均年薪20.36万,Java人才需求量最大
- 启动|拼多多深入布局母婴产业带 补贴+直播启动“母婴产品溯源”行动
- 程序员学英语第1天——JavaScript 程序测试的介绍1
- 三年Java开发,刚从美团、京东、阿里面试归来,分享个人面经
- RFID在冷链物流中的作用-RFID冷链资产管理解决方案
- 《深入理解Java虚拟机》:对象创建、布局和访问全过程
- java面试题整理
- Kotlin集合vs Kotlin序列与Java流
- 都说编程要逻辑好,如何理解这个逻辑
- Java安全之Javassist动态编程