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. 「newbee-mall新蜂商城开源啦」 前后端分离的 Vue 版本即将开源

    新蜂商城 Vue 版本 2019 年 10 月份我在 GitHub 开源仓库中上传了新蜂商城项目的所有源码,至今已经有小半年的时间了,感兴趣的可以去了解一下这个 Spring Boot 技术栈开发的商 ...

  2. TSP变形(三进制状压)

    题目:HDU3001 #include <bits/stdc++.h> using namespace std; ],vis[][],dis[][]; ][]; void init()// ...

  3. 系统通配符号、系统正则符号,grep

    系统通配符号.系统正则符号,grep 1 系统通配符号 系统通配符号:借助通配符号 匹配文件名称信息 1.1 *: 匹配所有(任意)字符信息 找寻以old开头的文件 find /oldboy -typ ...

  4. 博客第一天:Typora和Markown语法初始

    ------------恢复内容开始------------ Markdown学习 一级标题:#+空格 二级标题:##+空格 三级标题:###+空格 四级标题:####+空格 五级标题:#####+空 ...

  5. (一)Redis介绍

    1 背景 在早期的互联网Web 1.0时代,大部分企业还是采用传统的企业级单体应用架构,而一时间蜂拥而至的巨大用户流量使得这种架构难以支撑,通过对诸多系统架构实施以及对巨大用户流量的分析过程中发现,其 ...

  6. 一分钟明白MySQL聚簇索引和非聚簇索引

    MySQL的InnoDB索引数据结构是B+树,主键索引叶子节点的值存储的就是MySQL的数据行,普通索引的叶子节点的值存储的是主键值,这是了解聚簇索引和非聚簇索引的前提 什么是聚簇索引? 很简单记住一 ...

  7. Day_11【集合】扩展案例4_删除长度大于5的字符串,删除元素包含0-9数字的字符串

    分析以下需求,并用代码实现 1.定义ArrayList集合,存入多个字符串 如:"ab1" "123ad" "bca" "dadf ...

  8. 在培训机构花了好几万学Java,当了程序员还常被鄙视,这是招谁惹谁了?

    在之前的文章中说过,我是非计算机专业,通过参加培训进入程序员这行的. 入了程序员这行后,挺长一段时间在亲戚朋友中,我还是挺有面子的:家族里的第一个程序员,工作不用风吹日晒,收入比其他行业高不少,尤其是 ...

  9. Viterbi-Algorithm(维特比)算法

    CSDN博客:皮乾东  知乎:Htrying  微博:Htring的微博  微信公众号:自然语言处理爱好者(ID:NLP_lover)  文章来自:<数学之美> Viterbi-Algor ...

  10. [poj2778 DNA Sequence]AC自动机,矩阵快速幂

    题意:给一些字符串的集合S和整数n,求满足 长度为n 只含charset = {'A'.'T‘.'G'.'C'}包含的字符 不包含S中任一字符串 的字符串的种类数. 思路:首先对S建立ac自动机,考虑 ...