对象包装器与自动装箱
有时需要将 int 这样的基本类型转换为对象。 所有的基本类型都有一个与之对应的类。
例如, Integer 类对应基本类型 int。 通常, 这些类称为包装器 (wrapper) 这些对象包装器类拥有很明显的名字: Integer、 Long 、 Float、 Double 、 Short 、 Byte 、 Character 、 Void 和 Boolean (前6 个类派生于公共的超类 Number) 。对象包装器类是不可变的, 即一旦构造了包装器, 就不 允许更改包装在其中的值。 同时, 对象包装器类还是 final, 因此不能定义它们的子类。
由于每个值分别包装在对象中, 所以 ArrayList 的效率远远低于 int[ ]数组。 因此, 应该用它构造小型集合
自动装箱(autoboxing)
li st.add(3);
list.add(Integer.value0f(3));
这种变换被称为自动装箱 (autoboxing)
当将一个integer对象赋给一个int值时,将会自动地拆箱。也就是说,编译器将下列语句:
int n = list.get(i);
翻译成
int n = list.get(i).intValue();
甚至在算术表达式中也能够自动地装箱和拆箱。编译器将自动地插入一条对象拆箱的指令,然后进行自增计算,最后再将结果装箱。
自动装箱规范要求boolean、byte、char<=127, 介于-128-127之间的short和int被包装到固定的对象中。
关于自动装箱还有几点需要说明。首先,由于包装器类引用可以为null,所以自动装箱 有可能会抛出一个NullPointerException异常:
Integer n = null ;
System.out.println(2*n);
//Throws NullPointerException
另外,如果在一个条件表达式中混合使用Integer和Double类型,Integer值就会拆箱, 提升为double,再装箱为Double.装箱和拆箱是编译器认可的,而不是虚拟机。编译器在生成类的字节码时,插入必要的方法调用。虚拟机只是执行这些字节码。
由于 Java 方法都是值传递, 所以不可能编写一个下面这样的能够增加 整型参数值的 Java 方法。
public static void triple(int x) // won't work
{
x = 3 * x; // modifies local variable
}
将int 替换成 Integer 又会怎样呢?
public static void triple(Integer x) // won't work
{
...
}
问题是 Integer 对象是不可变的:包含在包装器中的内容不会改变。 不能使用这些包 装器类创建修改数值参数的方法。如果想编写一个修改数值参数值的方法, 就需要使用在 org.omg.CORBA 包中定义的 持有者 (holder) 类型, 包括 IntHolder、 BooI eanHo lder 等。 每个持有者类型都包含一个 公有(!)域值, 通过它可以访问存储在其中的值。