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中的自动装箱拆箱的更多相关文章

  1. 《Java中的自动装箱和拆箱功能.》

    //Java中的自动装箱和拆箱功能. class AutoboxingUnboxing { public static void main(String[] args) { //直接把一个基本类型变量 ...

  2. Java中的自动装箱与拆箱

    自动装箱和拆箱从Java 1.5开始引入,目的是将原始类型值转自动地转换成对应的对象.自动装箱与拆箱的机制可以让我们在Java的变量赋值或者是方法调用等情况下使用原始类型或者对象类型更加简单直接. 如 ...

  3. Java 的自动装箱拆箱

    Java 是面向对象的语言,其基本数据类型也就有了相对应的类,称为包装类.以下是基本数据类型对应的包装类: 基本数据类型 包装类 byte(1字节) Byte short(2字节) Short int ...

  4. java自动装箱拆箱总结

    对于java1.5引入的自动装箱拆箱,之前只是知道一点点,最近在看一篇博客时发现自己对自动装箱拆箱这个特性了解的太少了,所以今天研究了下这个特性.以下是结合测试代码进行的总结. 测试代码: int a ...

  5. Java八种基本数据类型的大小,以及封装类,自动装箱/拆箱的用法?

    参考:http://blog.csdn.net/mazhimazh/article/details/16799925 1. Java八种基本数据类型的大小,以及封装类,自动装箱/拆箱的用法? 原始类型 ...

  6. JAVA自动装箱拆箱与常量池

    java 自动装箱与拆箱 这个是jdk1.5以后才引入的新的内容,作为秉承发表是最好的记忆,毅然决定还是用一篇博客来代替我的记忆: java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的 ...

  7. 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 ...

  8. Java的自动装箱/拆箱

    概述 自JDK1.5开始, 引入了自动装箱/拆箱这一语法糖, 它使程序员的代码变得更加简洁, 不再需要进行显式转换.基本类型与包装类型在某些操作符的作用下, 包装类型调用valueOf()方法将原始类 ...

  9. JAVA的自动装箱拆箱

    转自:http://www.cnblogs.com/danne823/archive/2011/04/22/2025332.html 蛋呢  的空间 ??什么是自动装箱拆箱 基本数据类型的自动装箱(a ...

随机推荐

  1. Servlet --启动时创建、配置url、ServlectContext、初始化参数、获取资源

    servlet的版本的区别 2.5版本, Servlet的配置只支持在xml文件中的配置 3.0版本: Servlet的配置支持在xml文件中的配置, 也可以使用注解的方式, 默认使用注解 让服务器在 ...

  2. 关于【MySQL 子查询——查询最大值】的补充说明

    昨天在使用子查询查找最高分和最低分时遇上了一点问题,情况是这样的:如果找到的最高分或最低分是唯一值则不会有什么问题,但如果有其它班级学生的成绩恰好与查询的最高分或最低分相同时就会把那个学生的信息也显示 ...

  3. vue element select多选回显

    我们经常在使用 Element组件里面的 select多选 场景:添加账号的时候需要选择可见分公司(分公司为多选),添加成功之后可以编辑,需要回显添加时所提交的分公司 代码如下: 多选框: data( ...

  4. libevhtp初探

    libevent的evhttp不适合多线程,libevhtp重新设计了libevent的http API,采用了和memcached类似的多线程模型. worker线程的管道读事件的回调函数为htp_ ...

  5. OSG程序设计之osg::Group

    以下是一个简单的模型读取程序: #include <osgDB/ReadFile> #include <osgViewer/Viewer> #include <osg/N ...

  6. C - A Plug for UNIX POJ - 1087 网络流

    You are in charge of setting up the press room for the inaugural meeting of the United Nations Inter ...

  7. SpringBoot:Demo

    目录 Demo 准备工作 登录+拦截器 Restful CRUD Restful架构 查询所有员工 添加员工 员工修改功能 HiddenHttpMethodFilter 删除员工 定制错误页面 注销功 ...

  8. JVM 虚拟机&&类加载(一)

    虚拟机 虚拟机简介 Java 虚拟机(JVM)是运行java程序的抽象计算机,它是计算机设备的规范,可以采用不同方式进行实现,java 程序通过运行在JVM中实现跨平台,一次编译到处运行,不同的操作系 ...

  9. 【Hadoop离线基础总结】流量日志分析网站整体架构模块开发

    目录 数据仓库设计 维度建模概述 维度建模的三种模式 本项目中数据仓库的设计 ETL开发 创建ODS层数据表 导入ODS层数据 生成ODS层明细宽表 统计分析开发 流量分析 受访分析 访客visit分 ...

  10. requestAnimationFrame/cancelAnimationFrame——性能更好的js动画实现方式

    用js来实现动画,我们一般是借助setTimeout或setInterval这两个函数,css3动画出来后,我们又可以使用css3来实现动画了,而且性能和流畅度也得到了很大的提升.但是css3动画还是 ...