Java的包装类
Java作为一种面向对象的语言,和C语言最大的差别自然是OO(Object-Oriented),但是其基本数据类型仍旧沿用C语言的大部分内容,这与Java本身特性相违背,由此自然而然地衍生出了包装类(Wrapper Class)----在设计类时为每个基本数据类型设计了一个对应的类进行代表。
下表提供了八种数据类型和与之相对应的包装类:
基本数据类型 | 对应包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
包装类的基本方法
- 利用基本值参数创建包装类对象的构造函数
eg: Integer obj=new Integer(128); - 利用字符串参数创建包装类对象的构造函数
eg:new Double(“13.14”); - typeValue生成对象基本值(type为对象基本类型)
eg:obj.intValue(); - parseType将字符串转换为基本值
eg:Integer.parseInt(args[0]); - hashCode生成哈稀表代码
eg:obj.hashCode(); - 对同一个类的两个对象进行比较的equals()方法
eg:obj1.eauqls(obj2); - toString()将对象转化成字符串类型
eg:obj.toString();
装箱与拆箱
装箱
装箱就是自动将基本数据类型转换为包装器类型;
在装箱的时候自动调用包装类的valueOf(type)方法。
拆箱
拆箱就是自动将包装器类型转换为基本数据类型;
在拆箱的时候自动调用的则是包装类的typeValue方法。
equals()和 ==
数据类型 | equals() | == |
---|---|---|
字符串变量 | 字符串内容 | 对象在内存中首地址 |
非字符串变量 | 对象在内存中首地址 | 对象在内存中首地址 |
基本数据类型 | 不可用 | 值 |
包装类 | 内容 | 地址 |
几个练习
结果:
true
false
为什么会出现这样的结果?输出结果表明 i1 和 i2 指向的是同一个对象,而 i3 和 i4 指向的是不同的对象。此时只需一看源码便知究竟,下面这段代码是Integer的valueOf方法的具体实现:
public static Integer valueOf(int i) {
return i >= -128 && i <= Integer.IntegerCache.high ? Integer.IntegerCache.cache[i + 128] : new Integer(i);
}
从这2段代码可以看出,在通过valueOf方法创建Integer对象的时候,如果数值在 [-128,127] 之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。
上面的代码中 i1 和 i2 的数值为100,因此会直接从cache中取已经存在的对象,所以 i1 和 i2 指向的是同一个对象,而 i3 和 i4 则是分别指向不同的对象。
- 那么我们再来看看下面这段代码的输出结果是什么呢?
结果:
false
false
这是因为Double类的valueOf方法采用了与Integer类的valueOf方法不同的实现。
而之所以如此又是因为在某个范围内的整型数值的个数是有限的,而浮点数却不是。
Note: Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是相似的,Double、Float的valueOf方法的实现是类似的。
- 下面这段代码的输出结果是什么?
在这个例子里需要注意的是:当 “==” 运算符的两个操作数都是 包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)。另外,对于包装器类型,equals方法并不会进行类型转换。明白了这2点之后,上面的输出结果便一目了然:
第一个和第二个输出结果没有什么疑问。第三句由于 a+b 包含了算术运算,因此会触发自动拆箱过程(会调用intValue方法),因此它们比较的是数值是否相等。而对于c.equals(a+b)会先触发自动拆箱过程,再触发自动装箱过程,也就是说a+b,会先各自调用intValue方法,得到了加法运算后的数值之后,便调用Integer.valueOf方法,再进行equals比较。同理对于后面的也是这样,不过要注意倒数第二个和最后一个输出的结果(如果数值是int类型的,装箱过程调用的是Integer.valueOf;如果是long类型的,装箱调用的Long.valueOf方法)