Java 拆箱装箱

1、什么是装箱?什么是拆箱?
Java为每种基本数据类型都提供了对应的包装器类型,在Java 1.5之前如果要生成一个数值为10的Integer对象,必须这样创建:

Integer i = new Integer(10);

而在从Java1.5开始就提供了自动装箱的特性,如果要生成一个数值为10的Integer对象,只需要这样就可以了:

Integer i = 10;

这个过程会自动根据数值创建对应的Integer对象,这就是装箱。
那什么是拆箱呢?顾名思义,跟装箱对应的就是自动将包装器类型转换为基本数据类型:

Integer i = 10; //装箱
int n = i; //拆箱

简单一点说,装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动装包装器类型转换为基本数据类型。
下面简单介绍下基本数据类型以及所对应的包装器类型:

基础数据类型 包装器类型
int(4字节) Integer
byte(1字节) Byte
short(2字节) Short
long(8字节) Long
float(4字节) Float
double(8字节) Double
char(2字节) Character
boolean Boolean

2、装箱和拆箱是如何实现的

Integer i = 10;
int n = i;

感兴趣的可以反编译class文件之后看到,在装箱的时候自动调用的是Integer的valueOf(int) 方法。而在拆箱的时候自动调用的是Integer的intValue方法。其它的数据类型也有相关的xxValue等方法。因此可以用一句话总结装箱和拆箱的实现过程:
装箱过程就是通过调用包装器的valueOf()方法实现的,而拆箱过程是通过调用包装器的xxValue方法实现的。
自动装箱拆箱机制其实是编译时自动完成替换的。

3、相关面试题
3.1下面这段代码的输出结果是什么?

Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 150;
Integer i4 = 150;
System.out.print(i1 == i2); // 1
System.out.print(i3 == i4); //2

答:注释1返回true,注释2返回false。输出结果表明i1和i2指向的是同一个对象,而i3和i4指向的是不同的对象。至于为什么会有这个结果我们看下Integer的valueOf方法就明白了:

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

从上面源码可以看出,在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便会返回指向IntegerCache.cache中已经存在的对象引用,否则创建一个新的Integer对象。上面的代码中i1和i2的值都在这个区间,所以会直接从cache中取已经存在的对象,所以i1和i2指向同一个对象,而i3和i4则分别指向不同的对象

3.2下面这段代码的输出结果是什么?

        Double d1 = 100.0;
        Double d2 = 100.0;
        Double d3 = 150.0;
        Double d4 = 150.0;
        System.out.print(d1 == d2); //1
        System.out.print(d3 == d4); //2

答:注释1返回false,注释2返回false。具体原因可以查看下Double类的valueOf实现。

public static Double valueOf(double d) {
    return new Double(d);
}

至于为什么Double的valueOf会采用和Integer的valueOf方法不同的实现。很简单:在某个范围内的整型数值的个数是有限的,而浮点数不是。
注意:Integer、Short、Byte、Character、Long这几个类的valueOf方法实现是类似的。Double和Float的valueOf方法的实现是类似的。

3.3下面这段代码的输出结果是什么?

        Boolean b1 = true;
        Boolean b2 = true;
        Boolean b3 = false;
        Boolean b4 = false;
        System.out.print(b1 == b2); //1
        System.out.print(b3 == b4); //2

答:注释1返回true,注释2返回true。我们可以看下Boolean的valueOf

    public static Boolean valueOf(boolean b) {
        return b ? Boolean.TRUE : Boolean.FALSE;
    }

其中TRUE和FALSE分别为在Boolean中定义的2个静态成员属性

public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);

所以通过上面可以明白为什么都会返回true。

3.4下面这段代码的输出结果是什么?

        Integer i1 = 1;
        Integer i2 = 2;
        Integer i3 = 3;
        Long g = 3L;
        Long h = 2L;
        System.out.print(i3 == (i1 + i2));    //true
        System.out.print(i3.equals(i1 + i2)); //true
        System.out.print(g == (i1 + i2));     //true
        System.out.print(g.equals(i1 + i2));  //false
        System.out.print(g.equals(i1 + h));   //true

答:本题需要有一点要注意:当“==”运算符的两个操作数都是包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算数运算)则比较的是数值(会触发自动拆箱过程)。对于包装器类型,equals方法并不会进行类型转换。
因此i3 == (i1 + i2)会返回true,因为触发拆箱之后比较的就是数值。
g == (i1 + i2)返回true,会触发自动拆箱,再触动自动装箱。

3.5 谈谈Integer i = new Integer(xxx) 和 Integer i = xxx 两种方式的区别
答:a、第一种方式不会触发自动装箱过程;而第二种方式会触发
b、在执行效率和资源占用上的区别。第二种方式的执行效率和资源占用在一般情况下要优于第一种

3.6 Integer i = 1; i += 1; 做了哪些事情?
答:首先 Integer i = 1; 做了自动装箱,接着 i += 1; 先将 Integer 类型的 i 自动拆箱成 int,完成加法运行之后的 i 再装箱成 Integer 类型。

3.7 java 是否存在使得语句 i > j || i <= j 结果为 false 的 i、j 值?
答:存在,java 的数值 NaN 代表 not a number,无法用于比较,例如使 i = Double.NaN; j = i; 最后 i == j 的结果依旧为 false。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351

推荐阅读更多精彩内容

  • 自动装箱和拆箱从Java1.5开始引入,目的是将原始类型值转自动地转换成对应的对象。自动装箱与拆箱的机制可以让我们...
    GB_speak阅读 619评论 0 4
  • 九种基本数据类型的大小,以及他们的封装类。(1)九种基本数据类型和封装类 (2)自动装箱和自动拆箱 什么是自动装箱...
    关玮琳linSir阅读 1,882评论 0 47
  • 一、linux的目录结构 linux以树形目录结构的形式来构建整个系统。每一个目录不仅能使用本地磁盘分区的文件系统...
    bewhyy阅读 340评论 0 0
  • 入夜了,想起今天的感赏能写什么呢? 居然脑袋空白,光想着每天22:00整的闹铃响起,却不知道电话打...
    我是我的天涯阅读 133评论 0 2
  • 失去爱 走进孤独 你用沉默 打碎我的渴慕 我的脸上 全是你洒的冷落 你已离去 不再与我共离合 我的爱河 为你干涸 ...
    长河冬阳阅读 276评论 0 4