1、包装器的基本概念
int num = 10;
1
1
int num = 10;
如上 num 只是一个变量,但是在某些必须操作对象的场合,这样的变量不能使用了,因为变量不是对象。
其他基本数据类型也是如此,所以Java提供了一系列类,以便将基本数据类型当作对象进行操作,这些类,我们常常统称为包装器类。
基本数据类型 | 包装器类 |
boolean | Boolean |
byte | Byte |
char | Character |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
包装器类还封装了大量的静态方法,比如Character包装器类,可以调用(其他类不再展开,详细参考JDK):
- boolean isLetter(char ch) 判断字符ch是否为英文
- boolean isDigit(char ch) 判断字符ch是否为0~9之间的数字
- ...
获取包装器类:
- 使用new来调用构造方法,如 Double num = new Double(11.25);
- 使用对应包装器类的静态方法valueOf,如 Double num = Double.valueOf(11.25);
- 使用自动装箱/拆箱(JDK1.5之后),直接赋值,如 Double num = 11.25;
2、常用的类型转换
2.1 基本数据类型/字符串 --> 包装器类
包装器类中,静态方法 valueOf 不光是可以将基本输入类型转为包装器类,如果参数是字符串,也可以转换为对应的包装器类,如:
Double double1 = Double.valueOf(11.2);
Double double2 = Double.valueOf("11.2");
2
1
Double double1 = Double.valueOf(11.2);
2
Double double2 = Double.valueOf("11.2");
2.2 包装器类 --> 基本数据类型
除了Character和Boolean,数字类型的包装器类都继承了Number类,有一系列的 xxValue 方法,因此可以将包装器类转换为基本数据类型,甚至可以将Integer转换为int,或者double,如:
Integer tmp = new Integer(1314);
int tmp1 = tmp.intValue();
double tmp2 = tmp.doubleValue();
3
1
Integer tmp = new Integer(1314);
2
int tmp1 = tmp.intValue();
3
double tmp2 = tmp.doubleValue();
2.3 包装器类 --> String
直接调用包装器类的 toString 方法,可以转换为对应的字符串类型,如:
Integer tmp = new Integer(1314);
String tmpStr = tmp.toString();
2
1
Integer tmp = new Integer(1314);
2
String tmpStr = tmp.toString();
2.4 String --> 基本数据类型
除了Character和Boolean,数字类型的包装器类,有相应的静态方法 parseXxx,可以将字符串转换为相应的基本数据类型,如:
int numInt = Integer.parseInt("1314");
double numDouble = Double.parseDouble("11.25");
2
1
int numInt = Integer.parseInt("1314");
2
double numDouble = Double.parseDouble("11.25");
3、自动装箱和拆箱
为了让代码简练,Java1.5 引入了具有在原始类型和对象类型自动转换的装箱和拆箱机制。
自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱。因为这里的装箱和拆箱是自动进行的非人为转换,所以就称作为自动装箱和拆箱。
这意味着,很多场景下你不再需要去做所谓的基本数据类型和包装器类的转换了,一个典型的例子就是我们向ArrayList中增加基本数据类型时,要知道List是必须要求存入的是对象,也就是说我们应该存入前先将int转换为Integer,而实际上有了自动装箱:
ArrayList<Integer> intList = new ArrayList<Integer>();
intList.add(1); //autoboxing - primitive to object
intList.add(2); //autoboxing
3
1
ArrayList<Integer> intList = new ArrayList<Integer>();
2
intList.add(1); //autoboxing - primitive to object
3
intList.add(2); //autoboxing
同理,List获取出来的都是对象,而有了自动拆箱:
int number = intList.get(0); // unboxing
1
1
int number = intList.get(0); // unboxing
需要注意的是,包装器类之间的比较,因为其属于对象,直接使用“==”是不会触发自动装箱/拆箱的,要使用equals方法。但是在基本数据类型存在的情况下,则会出发自动装箱/拆箱。如下:
int i=0;
Integer j = new Integer(0);
System.out.println(i==j);
System.out.println(j.equals(i));
//结果返回分别是true,true
x
1
int i=0;
2
Integer j = new Integer(0);
3
System.out.println(i==j);
4
System.out.println(j.equals(i));
5
6
//结果返回分别是true,true
- 基本数据类型和包装器类进行“==”运算符的比较,包装器类会自动拆箱变为基本数据类型后再进行比较,因此Integer(0)会自动拆箱为int类型再进行比较,返回true
- 两个Integer类型进行“==”比较,如果其值在-128至127,那么返回true,否则返回false,这跟Integer.valueOf()的缓冲对象有关,这里不进行赘述
- 两个包装器类进行equals()比较,首先equals()会比较类型,如果类型相同,则继续比较值,如果值也相同,返回true
- 包装器类调用equals(),但是参数是基本类型,这时候,先会进行自动装箱,基本数据类型转为包装器类,再进行比较