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

最新文章

  1. 翻译:使用 ASP.NET MVC 4, EF, Knockoutjs and Bootstrap 设计和开发站点 - 1
  2. ATM
  3. eclipse通过ctrl+shift+t无法找到源文件类的解决方法
  4. windows和linux实现文件共享
  5. SSH 小总
  6. percona
  7. c# 隐藏 控制台应用程序
  8. windows系统调用 线程 启动与挂起
  9. 最牛B的编码套路(转)
  10. Unity3D Script Execution Order ——Question
  11. 高性能 TCP &amp;amp; UDP 通信框架 HP-Socket v3.2.3 正式宣布
  12. .NET Framework VS .NET Core
  13. 【LUOGU???】WD与地图 整体二分 线段树合并
  14. Barber paradox
  15. 获取ADO连接字符串
  16. npm i 出错
  17. shell基础入门(一)
  18. js数据类型转换 ----流程控制
  19. XtraBackup 备份原理
  20. 在TFS中获取项目,获取最新和上传(迁入)

热门文章

  1. 安装Chrome扩展程序xpath
  2. LeetCode 搜索旋转排序数组
  3. ubuntu 命令行以及目录的显示改为英文
  4. PostgreSQL 之 CREATE FUNCTION
  5. 停止monkey的方法
  6. CentOS7使用rpm安装mysql5.7
  7. Python生成随机数组的方法小结
  8. Hadoop 部署之 Spark (六)
  9. DB2的web可视化客户端工具
  10. VS开发】C中调用C++文件中定义的function函数