Java学习day032 对象包装器与自动装箱

使用的教材是java核心技术卷1,我将跟着这本书的章节同时配合视频资源来进行学习基础java知识。

day032   对象包装器与自动装箱


有时,需要将int这样的基本类型转换为对象。所有的基本类型都有一个与之对应的类。例如,Integer类对应基本类型int。通常,这些类称为包装器(wrapper)这些对象包装器类拥有很明显的名字:Integer、Long、Float、Double、Short、Byte、Character、Void和Boolean(前6个类派生于公共的超类Number)。对象包装器类是不可变的,即一旦构造了包装器,就不允许更改包装在其中的值。同时,对象包装器类还是final,因此不能定义它们的子类。

假设想定义一个整型数组列表。而尖括号中的类型参数不允许是基本类型,也就是说,不允许写成ArrayList。这里就用到了Integer对象包装器类。我们可以声明一个Integer对象的数组列表。

ArrayList<Integer> list=new ArrayList<>();

幸运的是,有一个很有用的特性,从而更加便于添加int类型的元素到ArrayLisy<lnteger>中。下面这个调用

list.add(3);

将自动地变换成

list.add(Integer.valueOf(3));

这种变换被称为自动装箱(autoboxing)。

相反地,当将一个Integer对象赋给一个int值时,将会自动地拆箱。也就是说,编译器将下列语句:

int n=list.get(i);

翻译成

int n=list.get(i).intValue();

甚至在算术表达式中也能够自动地装箱和拆箱。例如,可以将自增操作符应用于一个包装器引用:

Integer n=3;
n++;

编译器将自动地插人一条对象拆箱的指令,然后进行自增计算,最后再将结果装箱。

大多数情况下,容易有一种假象,即基本类型与它们的对象包装器是一样的,只是它们的相等性不同。大家知道,==运算符也可以应用于对象包装器对象,只不过检测的是对象是否指向同一个存储区域,因此,下面的比较通常不会成立:

Integer a=1000;
Integer b=1000;
if(a=b)...

然而,Java实现却有可能(may)让它成立。如果将经常出现的值包装到同一个对象中,这种比较就有可能成立。这种不确定的结果并不是我们所希望的。解决这个问题的办法是在两个包装器对象比较时调用equals方法。

关于自动装箱还有几点需要说明。首先,由于包装器类引用可以为null,所以自动装箱有可能会抛出一个NullPointerException异常:

Integer n=null;
System.out.println(2*n);//Throws NullPointerException

另外,如果在一个条件表达式中混合使用Integer和Double类型,Integer值就会拆箱,提升为double,再装箱为Double:

Integer n=1;
Double x=2.0;
System.out.println(true?n:x);//Prints 1.0

最后强调一下,装箱和拆箱是编译器认可的,而不是虚拟机。编译器在生成类的字节码时,插人必要的方法调用。虚拟机只是执行这些字节码。

使用数值对象包装器还有另外一个好处。Java设计者发现,可以将某些基本方法放置在包装器中,例如,将一个数字字符串转换成数值。

要想将字符串转换成整型,可以使用下面这条语句:

int x=Integer.parseInt(s);

这里与Integer对象没有任何关系,parselnt是一个静态方法。但Integer类是放置这个方法的一个好地方。

API注释说明了Integer类中包含的一些重要方法。其他数值类也实现了相应的方法。

 


 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值