深入理解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()方法将原始类 ...
随机推荐
- Flutter移动电商实战 --(24)Provide状态管理基础
Flutter | 状态管理特别篇 —— Provide:https://juejin.im/post/5c6d4b52f265da2dc675b407?tdsourcetag=s_pcqq_aiom ...
- MySQL 创建删除和选择数据库
使用 create 命令创建数据库,语法如下: CREATE DATABASE 数据库名; 删除数据库 drop database <数据库名>; 选择数据库 use 数据库名 Datab ...
- 图解centos7如何关闭ipv6仅使用ipv4
方法/步骤 使用ifconfig命令查看网卡信息,如果出现inet6 fe80::20c:29ff:fed0:3514,说明机器开启了ipv6,如下图所示: 编辑/etc/sysctl.c ...
- 阶段5 3.微服务项目【学成在线】_day03 CMS页面管理开发_10-修改页面-前端-修改页面
1.进入页面,通过钩子方法请求服务端获取页面信息,并赋值给数据模型对象 2.页面信息通过数据绑定在表单显示 3.用户修改信息点击“提交”请求服务端修改页面信息接口 3.3.3 修改页面 3.3.3.1 ...
- JAVA 基础编程练习题25 【程序 25 求回文数】
25 [程序 25 求回文数] 题目:一个 5 位数,判断它是不是回文数.即 12321 是回文数,个位与万位相同,十位与千位相同. package cskaoyan; public class cs ...
- Cognos Framework操作记录:开发复杂报表
设计一张数据库的表:TEST_001_ADDRESS 表结构: | 编号 | 姓名 | 省 | 市 | 县 | 公司 | 部门 | 职位 | | ---- | --- | -- | - | - | - ...
- 前端如何避免bug的产生?
项目环境:react生态圈 界面功能基本和:增(新增一条数据).删(删除一条数据).查(展示列表).改(修改数据)挂钩. 一.展示数据列表相关[判空,控制显示距离,分页是否有效,搜索是否有效] 1.渲 ...
- CJL.0.1.js
/*! * Cloudgamer JavaScript Library v0.1 * Copyright (c) 2009 cloudgamer * Blog: http://cloudgamer.c ...
- POJ2594 Treasure Exploration【DAG有向图可相交的最小路径覆盖】
题目链接:http://poj.org/problem?id=2594 Treasure Exploration Time Limit: 6000MS Memory Limit: 65536K T ...
- [转帖]IIS7配置Gzip压缩
IIS7配置Gzip压缩 https://www.cnblogs.com/coce/p/6804373.html II7中自带了gzip功能,理论上应该比ii6配置起来应该简单一点,但是容易出的问 ...