Java 自动装箱 自动拆箱
Java 自动装箱 自动拆箱
为什么会写这篇文章? 因为在比较两个
ArrayList<Integer>
元素的值是否完全对应相等时, 遇到了一个大坑明明都是-685, 怎么就不相等了呢? 起初猜想是因为Integer比较的是地址, 但5判断的是相等啊, 又经过一番搜索, 才明白, 遂写下以记录
自动装箱 自动拆箱于JDK1.5中引入
int常量池
要搞清楚上面这个问题, 就要了解常量池
JVM会自动维护八种基本类型的常量池,int常量池中初始化-128~127的范围
我们来看一下Integer.java
的源码来验证一下
JVM在启动时就已经将-128~127的Integer对象全部new出来, 因为这个范围内的数比较常用
自动装箱
定义: 自动将基本数据类型转换为封装类型(如int转为Integer)
1 | // 自动装箱 |
可以通过反编译class文件看出
valueOf
方法会判断数值在不在-128~127范围内, 在的话直接返回已经创建的Integer对象, 不在的话再new出来. 这也就解释了为什么最开始的问题中5是相等的, 而-685不相等
自动拆箱
定义: 自动将封装数据类型转换为基本类型(如Integer转为int)
1 | // 自动装箱 |
总结
最开始的问题中5相等, 是因为两个ArrayList<Integer>
的值都是通过add(int i)添加的, 换句话说, 都发生了自动装箱, 调用了valueOf
方法. 5在常量池中, 所以直接返回, 两个list中5相等
而-685不在常量池中, 都是在堆内存中new出来的, 地址不相等
当然如果Integer a = new Integer(5);
, Integer b = new Integer(5);
, a==b
为false, 因为此过程是直接new, 不会发生自动装箱, 也就不会调用valueOf
方法
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.