WEB开发网
开发学院WEB开发Jsp 体验J2SE 1.5新特性之装箱和拆箱 阅读

体验J2SE 1.5新特性之装箱和拆箱

 2008-01-05 20:02:51 来源:WEB开发网   
核心提示:J2SE 1.5提供了“Autoboxing”和“Auto-Unboxing”的机制,可以让编译器来自动完成在基本类型和它们的包裹对象之间的转化工作,体验J2SE 1.5新特性之装箱和拆箱,从而能够用一种更简单的方式,来避免同时存在两套类型系统所带来的一些麻烦,是J2SE 1.5中新加入的内容,其它包裹类也都有可以接受
  J2SE 1.5提供了“Autoboxing”和“Auto-Unboxing”的机制,可以让编译器来自动完成在基本类型和它们的包裹对象之间的转化工作,从而能够用一种更简单的方式,来避免同时存在两套类型系统所带来的一些麻烦。 本文介绍Autoboxing/Auto-Unboxing机制的使用方法、实质、发生时机、局限、对重载机制的影响以及对性能的妨碍等问题。
 
  传统上,在java程序中,可以往一个容器类(无论是Collection还是Map)里直接放入一个对象;但是假如打算放入的是一个数字、字符或布尔值的话,就要先加入一个“生成包裹它们的对象”的步骤。
  造成这种现象的原因是,在Java语言当中一直存在着两套非常不同的类型系统:

  一套是所谓的“引用类型”(Reference Types),包括所有的类和接口。这些类型的数据被看作对象,所以可以用一个Object型的变量来保存。

  一套是所谓的“基本类型”(PRimitive Types),包括:byte、short、int、long、float、double、char和boolean。这些类型的数据不是对象,因此也不能用Object型的变量来保存。

  同时采用这样两套类型系统,可以得到一些性能方面的好处——因为基本类型的数据不是对象,所以创建得更快、占用的空间更少、收回它们占用的资源也更轻易;但是,这样的做法同时也会造成一些编码方面的问题——例如,不能定义一个变量(或数组),让它既能保存基本类型的数据,又能保存引用类型的数据(类似的,也不能定义一个同时能匹配这两种类型的数据的形参,不过这个问题可以借助Java里的重载机制往返避)。

  实际上需要定义“不知道用来保存什么类型的数据”的变量(和形参)时,一般对这个问题采取回避的态度,将它们的类型定义成Object,然后借助可以称为“Boxing”和“Unboxing”的操作来解决Object不能涵盖基本类型的问题。

  1. Boxing和Unboxing操作

  所谓Boxing操作,是指通过生成一个能包裹基本类型数据的对象,来让基本类型的数据出现在只能接受引用类型的地方。

  清单1:手工Boxing的典型情况

Collection integers = new ArrayList();
for(int i = 0; i < 10; i++) {
integers.add(new Integer(i));
}
  用于生成这些的对象的类,被称作“包裹类”(Wrapper Classes)。Java中的包裹类有Byte 、Short、Integer、Long、Float、Double、Character和Boolean(都在java.lang包里定义)等八种,分别用于包裹byte、short、int、long、float、double、char和boolean类型的数据。

  而所谓Unboxing操作,则是指调用包裹类对象的相应方法,得到它们所代表的“基本类型的数据”,以便进行进一步的处置。

  清单2:手工Unboxing的典型情况

for(Iterator itr = integers.iterator(); itr.hasNext(); ) {
Integer i = (Integer) itr.next();
System.out.println(i.intValue() + 1);
}
  而在Java语言的最新版本——J2SE 1.5中,提供了“Autoboxing”和“Auto-Unboxing”的机制,可以让编译器来自动完成这些琐碎的操作,从而用一种更简单的方式,来整合两套类型系统。

  熟悉的生疏名词

  尽管这一对操作的历史很悠久,但是把它们称作“Boxing”和“Unboxing”的做法,基本是在出现“Autoboxing”和“Auto-Unboxing”的概念之后,才得到了广泛的接受。在那之前,它们似乎并没有通用的、专门的名字。不过由于那时也很少提及这两个概念,所以这个问题倒也没有造成什么严重的影响。

  2. 使用Autoboxing和Auto-Unboxing

  使用Autoboxing和Auto-Unboxing,并不需要什么非凡的步骤,一切都会在编译器的安排下自动发生。

  现在可以这样来对待一个int型的数据:

  清单3:自动完成的Boxing操作

Collection al = new ArrayList();
al.add(1);
  因为编译器会静静的把这段代码转换成接近这个样子:

  清单4:作了Autoboxing之后的等价形式

Collection al = new ArrayList();
al.add(Integer.valueOf(1));
  这里所用的能接受int类型的值为参数,生成Integer实例的valueOf方法,是J2SE 1.5中新加入的内容。其它包裹类也都有可以接受对应的基本类型的值为参数,生成对应的包裹类实例的valueOf方法加入。

  而这样对待一个Integer型的对象也是可以的:

  清单5:自动完成的Unboxing操作

Integer one = new Integer(1);
int two = one + 1;

Tags:体验 JSE 特性

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接