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 ...
随机推荐
- libevent(九)evhttp
用libevent构建一个http server非常方便,可参考libevent(六)http server. 主要涉及的一个结构体是evhttp: struct evhttp { /* Next v ...
- Qt for Android (三) 打开Android相册并选一个图片进行显示
Qt for Android (三) 这两天弄了一下android相册的相关功能.还是花了挺长时间的,这里总结一下,避免以后再踩坑.同时也在这篇文章里面补齐一些android开发的基础支持 打开And ...
- restful 架构风格的curd(增删改查)
restful架构 概念:REST指的是一组架构约束条件和原则,如果一个架构符合REST的约束条件和原则,就称之为RESTful架构. restful不是一个专门的技术,他是一个规范.规范就是写写代码 ...
- vim基础快捷键
vim快捷键 1. 移动光标 快捷键 作用 h 光标向左移动一个字符 j 光标向下移动一个字符 k 光标向上移动一个字符 l 光标向右移动一个字符 6j 向下移动6个字符 Ctrl+f 屏幕向下移动一 ...
- python学习之变量以及变量/标识符/关键字
Python成为一门易读.易维护,并且被大量用户所欢迎的.用途广泛的语言,代码简洁,功能强大,是使程序员能够专注于解决问题而不是研究语言本身.接下来我们先从它的语法开始学起 1.首先要懂得python ...
- 可怕!CPU竟成了黑客的帮凶!
本故事根据CPU真实漏洞改编 前情回顾 还记得我吗,我是阿Q,就是那个CPU一号车间的阿Q啊.如果你忘记了我,记得看看这里回忆一下哦:完了!CPU一味求快出事儿了! 自从我们车间用上了乱序执行和分支预 ...
- CF #635D Xenia and Colorful Gems 枚举+二分
Xenia and Colorful Gems 题意 给出三个数组,在每个数组中选择一个数字x,y,z,,使得\((x-y)^2+(y-z)^2+(x-z)^2\)最小. 思路 我们假设x<=y ...
- 4-JVM 参数
JVM 参数 标准参数:不会随着jdk版本的变化而变化.比如:java -version.java -help 非标准参数:随着JDK版本的变化而变化. -X参数[用的较少]非标准参数,也就是在JDK ...
- Mysql 常用函数(7)- length 函数
Mysql常用函数的汇总,可看下面系列文章 https://www.cnblogs.com/poloyy/category/1765164.html length 的作用 返回字符串的字节长度 注意: ...
- 正则表达式 [:graph:] 含义
[:graph:] 代表printable and visible的字符,是除空格符(空格键与[TAB]键)之外的所有按键, 控制字符不算[:graph:] https://www.regular-e ...
