深入理解Java自动装箱拆箱机制
1、自动装箱与拆箱的定义
装箱就是自动将基本数据类型转换为包装器类型(int-->Integer);
拆箱就是自动将包装器类型转换为基本数据类型(Integer-->int)。
Java中的数据类型分为两类:一类是基本数据类型,另一类是引用数据类型。如下图:

| 基本类型 | 二进制位数 | 分装类 |
| int | 32(4字节) | Integer |
| byte | 8(1字节) | Byte |
| long | 64(8字节) | Long |
| short | 16(2字节) | Short |
| float | 32(4字节) | Float |
| double | 64(8字节) | Double |
| char | 16(2字节) | Character |
| boolean | 1(1/8字节) | Boolean |
由上可知Java中的基本数据类型有八种分别是:int(4字节) byte(1字节) short(2字节) long(8字节) float (4字节) double(8字节) char(2字节) boolean(1byte)基本数据类型不是对象,不能使用对象的方法。将基本数据类型转换为对象就是自动装箱的过程。下面是基本数据类型与封装器类之间对应的关系。
2、自动装箱
public static void main(String[] args) {
int a=3;
//定义一个基本数据类型的变量a赋值3
Integer b=a;
//b是Integer 类定义的对象,直接用int 类型的a赋值
System.out.println(b);
//打印结果为3
}
上面的代码中 Integer b=a; 一个对象怎么赋值成了基本数据类型的变量,其实这就是自动装箱的过程,上面程序在执行Integer b=a;的时候调用了Integer.valueOf ( int i ) 方法,Integer b=a; 这段代码等同于:Integer b=Integer.valueOf ( a ) 。下面是对 Integer.valueOf ( int i ) 方法简化后的源码:
public static Integer valueOf(int i) {
if (i >= -128 && i <= 127)
return IntegerCache.cache[i + 127];
//如果i的值大于-128小于127则返回一个缓冲区中已存在的一个Integer对象
return new Integer(i);
//否则返回 new 一个Integer 对象
}
可以看到Integer.valueOf ( a )其实是返回了一个Integer的对象。因此由于自动装箱的存在Integer b=a 这段代码是没有毛病的。其实更简化的来写可以这样:Integer b=3,同样这段代码等价于:Integer b=Integer.valueOf (3 ) 。
上面的这段代码中:IntegerCache.cache[i + 127],下面是简化后的源码:
private static class IntegerCache {
static final Integer cache[];
//定义一个Integer类型的数组且数组不可变
static {
//利用静态代码块对数组进行初始化。
cache = new Integer[256];
int j = -128;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
//cache[]原来是一个Integer 类型的数组(也可以称为常量池),value 从-128到127,
public static Integer valueOf(int i) {
if (i >=-128 && i <= 127)
return IntegerCache.cache[i + (-IntegerCache.low)];
//如果装箱时值在-128到127之间,之间返回常量池中的已经初始化后的Integer对象。
return new Integer(i);
//否则返回一个新的对象。
}
}
从上面代码可知,IntegerCache 类在初始化的时候,生成了一个大小为 256 的integer 对象的常量池,并且integer.val 的值从-128-127之内,在自动装箱时候,基本数据类型在该范围内的,则直接从该缓存区获取对应的Ingeter对象并返回,超出该范围,则重新创建Ingeter对象并返回;
3、自动拆箱
public static void main(String[] args) {
Integer b=new Integer(3);
//b为Integer的对象
int a=b;
//a为一个int的基本数据类型
System.out.println(a);
//打印输出3。
}
当封装类自动拆箱时,其实 int a=b,自动调用了b.intValue()方法,这段代码等价于:int a=b.intValue(),来看看inValue()方法到底是什么,下面是源码:
//自动拆箱时调用的方法,并直接返回基本数据类型
public int intValue() {
return value;
}
private final int value;
//而自动装箱时,通过构造函数创建对应的封装类,并将该基本数据类型赋值给该类的静态成员变量
public Integer(int value) {
this.value = value;
}
4、相关题目
自动装箱和拆箱已经解决了,看看下面的代码输出什么:
public static void main(String[] args) {
//
Integer a=new Integer(123);
Integer b=new Integer(123);
System.out.println(a==b);//输出 false
//分别创建两个封装类对象,比较的对象的引用类型变量,则不相等
//2
Integer c=123;
Integer d=123;
System.out.println(c==d);//输出 true
//对于同一个值,且值在-128~127范围内,自动装箱时直接返回缓存区已存在的Ingeter对象,则他们的引用类型变量是相等的,c、f为指向同一个对象
//
Integer e=129;
Integer f=129;
System.out.println(e==f);//输出 false
//自动装箱时,值超过了-128~127范围内,重新创建Ingeter对象,则e、f为指向两个对象
//
int g=59;
Integer h=new Integer(59);
System.out.println(g==h);//输出 true
//当一个基本数据类型,跟封装类做对比时,封装类会自动拆箱成基本数据类型,然后再比较值得大小
}

原文:https://blog.csdn.net/MyArray/article/details/89381893
深入理解Java自动装箱拆箱机制的更多相关文章
- java自动装箱拆箱总结
对于java1.5引入的自动装箱拆箱,之前只是知道一点点,最近在看一篇博客时发现自己对自动装箱拆箱这个特性了解的太少了,所以今天研究了下这个特性.以下是结合测试代码进行的总结. 测试代码: int a ...
- JAVA自动装箱拆箱与常量池
java 自动装箱与拆箱 这个是jdk1.5以后才引入的新的内容,作为秉承发表是最好的记忆,毅然决定还是用一篇博客来代替我的记忆: java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的 ...
- Java 自动装箱/拆箱
自动装箱/拆箱大大方便了基本类型(8个基本类型)数据和它们包装类的使用 自动装箱 : 基本类型自动转为包装类(int >> Integer) 自动拆箱: 包装类自动转为基本类型(Integ ...
- Java自动装箱拆箱
一.装箱.拆箱定义 如果一个int型量被传递到需要一个Integer对象的地方,那么,编译器将在幕后插入一个对Integer构造方法的调用,这就叫做自动装箱.而如果一个Integer对象被放到需要in ...
- 那些年一起踩过的坑 — java 自动装箱拆箱问题
坑在哪里? 我们都知道Java的八种基本数据类型:int, short, long, double, byte, char, float, boolean 分别有各自对应的包装类型:Integ ...
- Java八种基本数据类型的大小,以及封装类,自动装箱/拆箱的用法?
参考:http://blog.csdn.net/mazhimazh/article/details/16799925 1. Java八种基本数据类型的大小,以及封装类,自动装箱/拆箱的用法? 原始类型 ...
- 全面理解java自动装箱和拆箱(转)
自动装箱和拆箱从Java 1.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()方法将原始类 ...
随机推荐
- 多进程之间的互斥信号量的实现(Linux和windows跨平台)
最近工作中遇到了一些关于文件读取权限的问题.当一个程序中对一个固定名称的文件做了读写的操作的时候,外界通过并发式的调用这个应用的时候,可能存在多个进程同时去操作这个文件,这个时候可能会造成调用失败的问 ...
- SQL-W3School-高级:SQL Date 函数
ylbtech-SQL-W3School-高级:SQL Date 函数 1.返回顶部 1. SQL 日期 当我们处理日期时,最难的任务恐怕是确保所插入的日期的格式,与数据库中日期列的格式相匹配. 只要 ...
- 阶段5 3.微服务项目【学成在线】_day03 CMS页面管理开发_13-删除页面-前端-Api调用
增加删除链接 <el-button size="small" type="text" @click="del(page.row.pageId)& ...
- sparkStream---1
1.本地scala版 import org.apache.spark._ import org.apache.spark.streaming._ import org.apache.spark.str ...
- scikit-learn机器学习(四)使用决策树做分类,并画出决策树,随机森林对比
数据来自 UCI 数据集 匹马印第安人糖尿病数据集 载入数据 # -*- coding: utf-8 -*- import pandas as pd import matplotlib matplot ...
- php-fpm 重启
查看php-fpm进程数:ps aux | grep -c php-fpm [root@ssy106c14c190c69 etc]# ps -ef | grep php-fpm --- 查看php- ...
- Opengl_入门学习分享和记录_03_渲染管线(三)借助顶点数组对象VAO提高绑定属性效率
目前我们已经知道了,如果想要顶点着色器解释理解我们的输入数据,就必须要按照以下繁琐的步骤:第一步:将输入的数据复制一份到缓冲区,供OpenGL使用.而这块新出现的区域由VBO管理和表示.(若有多个输入 ...
- c++学习笔记_6
前言:本笔记所对应的课程为中国大学mooc中北京大学的程序设计与算法(三)C++面向对象程序设计,主要供自己复习使用,且本笔记建立在会使用c和java的基础上,只针对与c和java的不同来写 多态 虚 ...
- 亿级mongodb数据迁移
1. 预先准备有效数据单号池,通过单号拉取数据处理 单号表默认为1 01 使用findAndModify 更新单号表状态为 2 读取单号 循环读取100 条 02 通过运单号批量查询 Aladin_W ...
- 【FFMPEG】Ubuntu上安装FFMPEG
在之前,我们成功地使用mingw+msys在Windows平台下编译FFmpeg(见 http://www.linuxidc.com/Linux/2014-11/109839.htm),并生成了ffp ...