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)); } |
| for(iterator itr = integers.iterator(); itr.hasnext(); ) { integer i = (integer) itr.next(); system.out.println(i.intvalue() + 1); } |
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器