java 拆箱和装箱

java是面向对象的语言,存在的类似于int,long等基础类型,有时候操作起来会不太方便,有时我们需要把基础类型转为包装类,这个过程就是装箱。简单看一下装箱和拆箱的定义:

  • 装箱:将基础数据类型(8个)的值封装在对象中
  • 拆箱:提取封装类的对象中提取基础数据类型的值

举例:

// 装箱:
Integer number = 100;
Integer number1 = Integer.valueOf(100);
// 拆箱:
int number2 = number;
int number3 = number.intValue();

从上面的例子我们可以看到,java装箱的写法有两种,但实际上这两个表达方式是一样的,第一个Integer number = 100其实质就是Integer number1 = Integer.valueOf(100) 那为什么可以写第一种表达方式呢?
这就是java的自动装箱(autoboxing)和拆箱,当将一个基础类型赋值给包装类类型时,编辑器将把第二行的语句,翻译成第三行的语句,而相反,如果是将包装类类型赋值给基础类型时,系统将自动拆箱,如上面的第五行代码的本质就是第六行代码。

而关于自动装箱有一个小陷阱,我们可以先看一下下面的三组代码:

    // 第一组:
    Integer c = 3;
    Integer d = 3;
    Integer e = 321;
    Integer f = 321;
    System.out.println(c == d);
    System.out.println(e == f);

执行结果:true,false。为什么看起来相同,但比较结果会不同呢?
其实这就是自动装箱的一个小的陷阱,根据自动装箱的规范,要求-128~127之间的short和int被包装到固定的对象中,即它们可以被重用。因此,第二个,321的值不在范围内,是不同的对象,因此为false

    // 第二组:
    Integer number1 = 130;
    Integer number2 = 60;
    Integer number3 = 70;
    Integer number4 = 130;
    System.out.println(number1 == number4);
    System.out.println(number1 == (number2 + number3));

执行结果:false,true;第一个结果很好知道结果,因为上面第一组已经讲明了,但为什么第二个会是true呢?
其实,这里也有一个陷阱,就是包装类的“==”运算在不遇到算数运算符的情况下,不会自动拆箱。因此,第一个式子,由于两个的范围超过了第一组提到的范围,因此是false,但第二个式子中,由于出现了运算符,因此将被转为:number1.longValue() == (long)(number2.intValue() + number3.intValue()) 转换为基础类型之间的“==”,即比较值是否相等了。因此为true

    // 第三组:
    Integer a = 1;
    Integer b = 2;
    Long g = 3L;
    System.out.println(g == (a + b));
    System.out.println(g.equals(a + b));

执行结果:true,false。
在第二组,解释过包装类的”==“运算的拆箱问题,因此可以判断出,第一个为true,而对于第二个,我们要注意到,equals()不处理类型的转换问题,即两者是不同的基础类型,因此第二个为false

猜你喜欢

转载自blog.csdn.net/Applying/article/details/80692752