Java对象包装器与自动装箱
有时候,需要将int这样的基本类型转换为对象。所有的基本类型都有与之对应的类。例如,Integer类对应基本类型int。通常,这些类称为包装器(wrapper)。
自动装箱:
list.add(3);(自动转换)=> list.add(Integer.valueOf(3)); // 这种变换称为自动装箱。
自动拆箱:
int n = list.get(i); // 将一个Integet对象赋值给一个int ,自动拆箱。
包装类注意要点:
Integer a = 1;
Integer b = 1;
if(a == b) { // 这里不会自动拆箱,所以比较的是对象的地址值
...
}
Integer n = null;
System.out.println(2 * n); // throws NullPointerException
Integer n = 1;
Double x = 2.0;
System.out.println(true ? n : x); // print 1.0
// 如果在一个表达式中混合使用Integer和Double类型,Integer值就会自动拆箱,提升为double,再装箱为Double。
最后再强调以下,装箱和拆箱的编译器要做的工作,而不是虚拟机。编译器在生成字节码的时候会插入必要的方法调用。虚拟机只是执行这些字节码。
**注意:**包装器类是不可以改变的,即一旦构造的包装器,就不允许改变包装在其中的值。同时,包装器类还是final,因此不能派生他们的子类。
举例:
public static void main(String[] args) {
int n = 1;
triple(n);
System.out.println(n); // print 1
}
public static void triple(int x) {
x = 3 * x;
}
java方法的参数是按值传递,只是传进去一个副本,而没有改变原来的值。
将int替换为Integer:
public static void main(String[] args) {
Integer n = 1;
triple(n);
System.out.println(n); // print 1
}
public static void triple(Integer x) {
x = 3 * x;
}
包装类对象的值不允许改变。
解决问题的方法:
可以使用org.omg.CORBA包中定义的某个持有者类型,例如IntHolder、BooleanHolder等。每个持有者类型都包含一个公共字段value,通过它可以访问存储在其中的值。
public static void main(String[] args) {
IntHolder n = new IntHolder(1);
triple(n);
System.out.println(n.value); // print 3
}
public static void triple(IntHolder x) {
x.value = 3 * x.value;
}