Java中的自动装箱拆箱
Java中的自动装箱拆箱
一、自动装箱与自动拆箱
自动装箱就是将基本数据类型转换为包装类类型,自动拆箱就是将包装类类型转换为基本数据类型。
1 // 自动装箱
2 Integer total = 90;
3
4 // 自动拆箱
5 int totalprim = total;
以 整数型 Integer 为例 ,从上面代码分析:装箱与拆箱的过程
(一)、自动装箱
total声明的是包装类型Integer,数值90是数据常量,当执行Integer total = 90时,系统为我们执行了Integer total = Integer.valueOf(99);
首先看一下:valueOf(int i)方法源码:IntegerCache.low = -128,IntegerCache.high = 127,IntegerCache.cache[ ]是Integer类型的数组

首先判断 i 的大小:如果 i =< -128或者i >= 127,否则就创建一个Integer对象,否则返回 IntegerCache.cache[i + 128];
然后再看Integer的构造方法:


Integer定义了 一个 private final int value; 当创建一个Integer对象,就会给这个变量初始化。第二个构造方法传入的是一个String变量,它会先把它转换成一个int值,然后进行初始化。
IntegerCache.cache[ ]数组是 Integer 的内部类,定义了 static final Integer cache[]; 它是一个静态的Integer数组对象,也就是说最终valueOf返回的都是一个Integer对象。
所以我们这里可以总结一点:装箱的过程会创建对应的对象,这个会消耗内存,所以装箱的过程会增加内存的消耗,影响性能。
(二)、自动拆箱
totalprim 声明的基本数据类型 int,total 是 包装类型 Integer ,当执行 int totalprim = total时,系统会自动调用 intValue()方法。首先看一下intValue方法:
intValue方法较简单,直接返回 value 的值。
二、相关问题
自动装箱时,分别有两种情况:
1、i >= 128 || i < -128 =====> new Integer(i)
2、i < 128 && i >= -128 =====> IntegerCache.cache[i + 128]
IntegerCache.cache[ ] 是Integer 的内部类中定义的数组对象,本来已经创建好了,也就是说在i >= 128 || i < -128是会创建不同的对象,在i < 128 && i >= -128会根据 i 的值返回已经创建好的指定的对象。
举个例子:

通过执行上面的代码,分别输出了 true 和 false,数值一样,结果却不同,这是为什么呢?
①、i1 和 i1 都赋值为100,属于自动装箱的第二种情况,所以返回的是IntegerCache.cache[ ]数组中的对象,由于引用的是同一个 Integer 对象,所以他们的地址值是相等的,即他们是相等的。
②、i3 和 i4 都赋值为200,属于自动装箱的第一种情况,valueOf 方法会生成新的对象并返回,由于是分别引用的对象,两个对象的地址值不同,所以 “==” 判断时,他们是不相等的。
三、浮点型和布尔型的装箱拆箱
(一)、浮点型

数值相同,结果和 Integer 不同 ,和 Integer 类似,当调用 Double d1 = 100.0 时,系统会调用valueOf(double d),首先看一下源码 :

每次调用 valueOf 方法时,都会新生成一个 Double 对象 ,所以他们引用对象的地址值都不一样,因为 Integer 内部维护了一个IntegerCache.cache[ ] ,而IntegerCache.cache[ ]对象在整数型中的长度是固定的,所以在满足范围时返回的是同一个引用对象;而浮点型数据范围是无限大的,定义数组不太现实,所以直接生成新的对象。
(二)、布尔型

可以看到返回的都是true,也就是它们执行valueOf返回的都是相同的对象。和上面类似,当调用 Boolean b1 = false 时,系统会调用valueOf(boolean b),首先看一下源码 :

可以看到它并没有创建对象,因为在内部已经提前创建好两个常量,因为它只有两种情况,这样也是为了避免重复创建太多的对象。
(三)、小结
- 整数型派别:Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。
- 浮点数型派别:Double、Float的valueOf方法的实现是类似的。每次都返回不同的对象。
四、基础数据类型与包装类进行 ==、+、-、*、/ 运算
(一)运算
当基本数据类型进行普通的运算时,直接进行运算。
当包装类进行运算时,会先将包装类拆箱成基本数据类型,然后进行运算。
(二)、equals与 “==” 比较
包装类型重写了 Object 的 equal 方法,equal 比较的是内容本身,并且我们也可以看到equal的参数是一个Object对象,我们传入的是一个int类型,所以首先会进行装箱,然后比较对象里面的value值。
“==”运算符的两个操作数如果都是包装类类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)。
五、总结
- 装箱操作会创建对象,频繁的装箱操作会消耗许多内存,影响性能,所以可以避免装箱的时候应该尽量避免。
- equals(Object o) 因为原equals方法中的参数类型是封装类型,所传入的参数类型(a)是原始数据类型,所以会自动对其装箱,反之,会对其进行拆箱
- 当两种不同类型用==比较时,包装器类的需要拆箱, 当同种类型用==比较时,会自动拆箱或者装箱
Java中的自动装箱拆箱的更多相关文章
- 《Java中的自动装箱和拆箱功能.》
//Java中的自动装箱和拆箱功能. class AutoboxingUnboxing { public static void main(String[] args) { //直接把一个基本类型变量 ...
- Java中的自动装箱与拆箱
自动装箱和拆箱从Java 1.5开始引入,目的是将原始类型值转自动地转换成对应的对象.自动装箱与拆箱的机制可以让我们在Java的变量赋值或者是方法调用等情况下使用原始类型或者对象类型更加简单直接. 如 ...
- Java 的自动装箱拆箱
Java 是面向对象的语言,其基本数据类型也就有了相对应的类,称为包装类.以下是基本数据类型对应的包装类: 基本数据类型 包装类 byte(1字节) Byte short(2字节) Short int ...
- java自动装箱拆箱总结
对于java1.5引入的自动装箱拆箱,之前只是知道一点点,最近在看一篇博客时发现自己对自动装箱拆箱这个特性了解的太少了,所以今天研究了下这个特性.以下是结合测试代码进行的总结. 测试代码: int a ...
- Java八种基本数据类型的大小,以及封装类,自动装箱/拆箱的用法?
参考:http://blog.csdn.net/mazhimazh/article/details/16799925 1. Java八种基本数据类型的大小,以及封装类,自动装箱/拆箱的用法? 原始类型 ...
- JAVA自动装箱拆箱与常量池
java 自动装箱与拆箱 这个是jdk1.5以后才引入的新的内容,作为秉承发表是最好的记忆,毅然决定还是用一篇博客来代替我的记忆: java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的 ...
- java基础1.5版后新特性 自动装箱拆箱 Date SimpleDateFormat Calendar.getInstance()获得一个日历对象 抽象不要生成对象 get set add System.arrayCopy()用于集合等的扩容
8种基本数据类型的8种包装类 byte Byte short Short int Integer long Long float Float double Double char Character ...
- Java的自动装箱/拆箱
概述 自JDK1.5开始, 引入了自动装箱/拆箱这一语法糖, 它使程序员的代码变得更加简洁, 不再需要进行显式转换.基本类型与包装类型在某些操作符的作用下, 包装类型调用valueOf()方法将原始类 ...
- JAVA的自动装箱拆箱
转自:http://www.cnblogs.com/danne823/archive/2011/04/22/2025332.html 蛋呢 的空间 ??什么是自动装箱拆箱 基本数据类型的自动装箱(a ...
随机推荐
- Gitlab常规操作
一.Git和SVN的区别 和SVN类似,Git是一个版本控制系统(Version Control System,VCS),不同的是SVN为集中式版本控制系统,为单一的集中管理的服务器,保存所有文件的修 ...
- 数据可视化:使用python代码实现可视数据随机漫步图
#2020/4/5 ,是开博的第一天,希望和大家相互交流学习,很开森,哈哈~ #像个傻子哟~ #好,我们进入正题, #实现功能:利用python实现数据随机漫步,漫步点数据可视化 #什么是 ...
- Java笔记(day18-19)
泛型: jdk1.5出现的安全机制. 好处: 1,将运行时期的问题ClassCastException转到了编译时期. 2,避免了强制转换的麻烦. <>:当操作的引用数据类型不确定的时候. ...
- 看直播 csust oj
看直播 Description 小明喜欢看直播,他订阅了很多主播,主播们有固定的直播时间 [Li, Ri] . 可是他网速只有2M,不能同时播放两个直播,所以同一时间只能看一个直播. 并且他只会去看能 ...
- Coursera课程笔记----计算导论与C语言基础----Week 7
C语言中的数据成分(Week7) 内存 把内存想象成长带,带子上有许多方格,每个方格有8位(8bit) 2^10 = 1024 1B = 8 b 1KB = 1024Byte MB.GB.TB.PB- ...
- MinorGC前检查
- 【Hadoop离线基础总结】MapReduce案例之自定义groupingComparator
MapReduce案例之自定义groupingComparator 求取Top 1的数据 需求 求出每一个订单中成交金额最大的一笔交易 订单id 商品id 成交金额 Order_0000005 Pdt ...
- 01背包问题,dp和贪心解法(c++11)
dp解法: 令dp[i]表示容量为i的背包所能得到的最大价值,考虑在当前物品集合中加入1个新考虑的物品i,则有如下状态转移方程:dp[j] = max(dp[j], dp[j - weight[i]] ...
- linux --开机自动挂载硬盘【转】
转:http://c.biancheng.net/view/900.html 了解了 mount 命令之后,读者可能会问,系统如何在开机时自动挂载硬盘,它又是怎么知道哪些分区是需要挂载的呢? 很简单, ...
- JavaScript 事件参考
onabort 图像加载被中断 onblur 元素失去焦点 onchange 用户改变域的内容 onclick 鼠标单击事件 ondblclick 鼠标双击事件 onerror ...
