开发者社区> 程序员鱼丸> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

Java装箱与自动拆箱

简介: Java 编译器在`基本数据类型`和其对应的`对象封装类型`之间进行自动转换.例如将`int`转成`Integer`,将`char`转成包装类`Character`等等.其他基本数据类型的转换如下:
+关注继续查看

Java装箱与自动拆箱

介绍

Java 编译器在基本数据类型和其对应的对象封装类型之间进行自动转换.例如将int转成Integer,将char转成包装类Character等等.其他基本数据类型的转换如下:

Java 中 8 种基本数据类型

基本数据类型类型大小包装类取值范围取值范围Pro
byte数值型8bitByte-2^7 ~ 2^7-1-128 ~ 127
short短整形16bitShort-2^15 ~ 2^15-1-32768 ~ 32767
int数值整型32bitInteger-2^31 ~ 2^31-1-2147483648 ~ 2147483647
long数值长整形64bitLong-2^63 ~ 2^63-1-9223372036854775808 ~ 9223372036854775808
float单精度数值型32bitFloat 3.4e-45 ~ 1.4e38
double双精度数值型64bitDouble 4.9e-324 ~ 1.8e308
char短整形16bitCharacter0~65535\u0000 ~ \uffff
boolean布尔值8bit(争议)Boolean//

反之,从包装类转换成基本数据类型叫拆箱.例如从Integerint或者从包装类Long转换成基本数据类型long.

简单的装箱示例

Integer numA = 10;
Character charA  = 'a';

从原始数据类型创建整数对象

Integer b = new Integer(9);

看一下下面的代码:

List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
    li.add(Integer.valueOf(i));

上面的代码将 Java 基本数据类型 int ,而不是对应的 Integer 对象添加到 list 集合中,代码为什么会编译通过呢?
因为它从 i 创建了一个 Integer 对象并将该对象添加到 li集合中.
因此,编译器在运行时将之前的代码转换为以下代码:

List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
    li.add(Integer.valueOf(i));

将基本数据类型值(例如 int)转换为相应包装类(Integer)的对象称为自动装箱。当基本数据类型在下面的使用情况的时候,会进行自动装箱:

  • 作为参数传递给需要相应包装类的对象的方法。
  • 赋值给相应包装类的变量.

自动拆箱

int a = 9;
Integer b = new Integer(9);
System.out.println(a==b);
// 返回true

数学运算 +, %, += 不适用于 Integer 对象。

Java 编译器编译代码时没有错误,因为它自动执行拆箱,在运行时调用 intValueInteger 转换为 int.

System.out.println(a==b.intValue());

将包装类型 (Integer) 的对象转换为其对应的原始 (int) 值称为拆箱。当包装类使用情况如下的时候,会进行自动拆箱:

  • 作为参数传递给需要相应原始类型值的方法

分析如下代码:

public class TestTran {
    public static void main(String[] args) {
        unboxing(new Integer(9));
    }
    public static void unboxing(int testId) {
        System.out.println(testId);
    }
}

可以看到参数需要的是基本数据类型.传过去一个 Integer 对象,编译器没有报错.因为作为参数传递给需要相应原始类型值的方法,Java 编译器做了自动拆箱的操作.

  • 赋值给相应原始类型的变量

分析如下代码:

Integer a = new Integer(9);
int b =a;

当把对应的包装类型 b 对象,赋值给给相应原始类型的变量的时候.Java 编译器就会做自动拆箱的操作.

自动转换(拓展)

从低范围转到高范围类型转换属于自动类型转换, 是 JVM 自动进行转换的.

如上图中,byte char short这三个是平级的
自动转型的示例代码如下:

int num = 100;
double numPro = num;
System.out.println("转换前:" + num);
System.out.println("转换后:" + numPro);

代码输出如下:

转换前:100
转换后:100.0

面试题

1.给出如下代码,请回答输出了什么

public static void main(String[] args) {
    Integer numA = 100;
    Integer numB = 100;
    Integer numC = 128;
    Integer numD = 128;
    System.out.println(numA == numB);
    System.out.println(numC == numD);
}

想一下会输出什么,这样的面试题层出不穷,有没有什么好应对的方式
理理清楚自动装箱与拆箱,例如开篇的表格中有一个范围,Integer 的范围
Integer 把这个范围(-128 ~ 127)当成了一个缓存池,如果不在这个范围会使用 new 创建
所以现在的代码输出是:

true
false

2. Java 1.5 的自动装箱拆箱机制是编译时执行还是虚拟机运行时执行

答:编译时执行.

3.给出如下代码,请回答输出了什么

public static void main(String[] args) {
    Double numA = 10.0;
    Double numB = 10.0;
    System.out.println(numA == numB);
    System.out.println(numA.equals(numB));
    System.out.println(numA == 10);
}

上面的结果为 false true true
分析: 为什么 System.out.println(numA == 10)也是true
我这里使用 IDEA 查看编译的字节码,如下:

LINENUMBER 10 L6
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
ALOAD 1
INVOKEVIRTUAL java/lang/Double.doubleValue ()D
LDC 10.0
DCMPL
IFNE L7
ICONST_1
GOTO L8

因为做了拆箱操作,等同于System.out.println(numA.doubleValue() == 10);

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Java - 装箱 / 拆箱(下)
Java - 装箱 / 拆箱(下)
22 0
JAVA 入坑教程 | 章节九 详解java的装箱和拆箱
简单点,代码的方式简单点,装逼的方式请省略,我们又不是演员,别设计那些情节 什么是装箱?什么是拆箱?代码如何展示? 装箱过程是怎样的?拆箱过程是怎样的? 有问题可加入安卓QQ群: 246231638 装箱和拆箱的概念 简单点,代码的方式简单点,装...
1152 0
java-基础-装箱与拆箱
八种基本数据类型的大小,以及他们的封装类。 八种基本数据类型,int ,double ,long ,float, short,byte,character,boolean 对应的封装类型是:Integer ,Double ,Long ,Floa...
915 0
[Java开发之路](23)装箱与拆箱
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SunnyYoona/article/details/50991203 1. 简介 大家对基本数据类型都非常熟悉,例如 int、float、double、boolean、char 等。
755 0
深入剖析Java中的装箱和拆箱(转)
 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题。本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱、拆箱相关的问题。   以下是本文的目录大纲:   一.什么是装箱?什么是拆箱?   二.装箱和拆箱是如何实现的   三.面试中相关的问题 一.什么是装箱?什么是拆箱?   在前面的文章中提到,Java为每种基本数据类型都提供了对应的包装器类型,至于为什么会为每种基本数据类型提供包装器类型在此不进行阐述,有兴趣的朋友可以查阅相关资料。
860 0
Java高新技术1---增强for循环 ---装箱与拆箱享元设计模式--自己写枚举--可变长度的参数
其实这些知识是我在 看张孝祥老师的Java视频的时候 记录的  ,我可以负责任的说 对于 入门人员来说  这部视频 是 精粹 ,可以 3天内 带你 进入 Java的 另一个 境界 。 话不多说 ,不信 自己去看吧  。
801 0
18
文章
2
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载