Java
大约 3 分钟
Java
目录
对象包装器与自动装箱
API: java.lang.Integer 1.0
API: java.text.NumberFormat 1.1
包装器(wrapper)
概念
- 有时,需要将int这样的基本类型转换为对象。所有的基本类型都有一个与之对应的类。 例如,Integer类对应基本类型int。通常,这些类称为包装器
- 这些对象包装器类拥有很明显的名字: Integer、Long、Float、Double、Short、Byte、(前6个类派生于公共的超类Number) Character、Void和Boolean
特性
- 对象包装器类是不可变的,即一旦构造了包装器,就不允许更改包装在其中的值(除非拆箱再装箱)
- 对象包装器类还是final,因此不能定义它们的子类
使用场景举例
想定义一个整型数组列表。而尖括号中的类型参数不允许是基本类型。就用到了Integer对象包装器类
ArrayList<Integer> list = new ArrayList<>();
可以将某些基本方法放置在包装器中 例如类型转化的方法
// 与Integer实例无关,parseInt是一个静态方法 int x = Integer.parseInt(s); // 字符串转整型
自动装箱(autoboxing)
自动装箱
大家可能认为自动打包(autowrapping)更加合适,而“装箱(boxing)”这个词源自于C#
list.add(3);
// 会自动变为:
list.add(Integer.valueOf(3));
自动拆箱
int n = list.get(i);
// 会自动变成
int n = list.get(i).intValue();
算术表达式中自动拆箱和装箱
Integer n = 3;
n++; // 自动地插入一条对象拆箱的指令,然后进行自增计算,最后再将结果装箱
类型变化中自动拆箱和装箱
Interger n = 1;
Double x = 2.0;
System.out.println(true?n:x); // Prints 1.0
// 如果在一个条件表达式中混合使用Integer和Double类型:
// Integer值会拆箱,提升为double,再装箱为Double
补充
自动包装器的相等性
基本类型与它们的对象包装器是一样的,只是它们的相等性不同
在两个包装器对象比较时调用equals方法,而不要用==
Integer a = 1000;
Integer b = 1000;
if (a==b) ... // 结果是不确定的:可能相等也可能不等
// 原因:自动装箱规范要求boolean、byte、char≤127,介于-128~127之间的short和int被包装到固定的对象中
// 如果a和b初始化为100,则比较结果是成立的
// 解决这个问题的办法是在两个包装器对象比较时调用equals方法
包装器引用null
由于包装器类引用可以为null,所以自动装箱有可能会抛出一个NullPointerException异常
Integer n = null;
System.out.println(2*n); // Throws NullPointerException
依赖编译器而非虚拟机
装箱和拆箱是编译器认可的,而不是虚拟机
如何通过方法修改包装器的数值?通过持有者类型
(这里我也不是很懂)
基本类型值传递,没办法修改值Integer对象不可变,没办法修改值需要使用在org.omg.CORBA包中定义的
持有者(holder)类型
:包括IntHolder、BooleanHolder等。 每个持有者类型都包含一个公有域值,通过它可以访问存储在其中的值public static void triple(IntHolder x){ x.value = 3*x.value; }