Java基础知识(一)对象包装器

对象包装器

每个基本类型都有一个对应的类,称作包装器wrapper

/* extends Number */
// Interger         <-> int
// Long         <-> long
// Float        <-> float
// double       <-> double
// Short        <-> short
// Byte         <-> byte

/* not extends Number */
// Character        <-> character
// Void         <-> void
// Boolean      <-> boolean

对象包装器是不可变的:一旦构造了包装器,就不允许更改包装在其中的值。

对象包装器是final的:不能定义对象包装器的子类。

自动装箱(auto boxing)

声明一个Integer对象的数组列表,并添加一个值为3的Integer对象。

// 由于值包装在对象中,ArrayList<Integer>的效率远低于int[]数组。
ArrayList<Integer> list = new ArrayList<>();
// 等价于list.add(Integer.valueOf(3));
list.add(3);

相反地,将Integer对象赋值给int变量时,会自动拆箱

// 编译器将以下语句翻译成int n = list.get(i).inValue();
int n = list.get(i);

在算术表达式中也能够自动地装箱和拆箱。

Integer n = 3;
// 编译器会自动地插入一条对象拆箱指令,在自增计算执行后,执行装箱指令。
n++;

包装器的比较

对象包装器的相等性与基本类型是不同的:

Integer a = 1000;
Integer b = 1000;
// ==检测a和b是否指向同一个存储区域,结果是false
System.out.println(a == b);
// equals方法比较a和b包装的值,结果是true
System.out.println(a.equals(b));

自动装箱对基本类型的值的范围有规范要求:booleanbytechar127,介于-128~127之间的shortint被包装在固定的对象中,即指向相同的存储区域。

Integer a = 100;
Integer b = 100;
// 此时a和b指向同一个存储区域,结果是true
System.out.println(a == b);

引用null异常

包装器引用null时,自动装箱可能会抛出NullPointerException异常:

Integer n = null;
// 由于n引用null,执行2 * n时会将n自动拆箱取值,抛出NullPointerException异常。
System.out.println(2 * n);

自动升级

再一个条件表达式中混合使用IntegerDouble时,Integer值会拆箱提升为double,再装箱为Double

Integer n = 1;
Double x = 2.0;
// n升级为Double,结果是1.0
System.out.println(true ? n : x);

:装箱和拆箱是编译器认可的,而不是虚拟机。编译器再生成类的字节码时,会插入必要的方法调用。

猜你喜欢

转载自www.cnblogs.com/aries99c/p/12388554.html