黑马程序员技术交流社区

标题: 2. 包装类 [打印本页]

作者: 段燚涛    时间: 2015-8-8 13:58
标题: 2. 包装类
2. 包装类
2.1. 8个基本类型的包装类

我们知道java是面向对象的语言,其精髓之一是可以使用多态性,提高程序的灵活度。但是java中有8个基本类型:byte,short,int,long,float,double,char,boolean。它们是以值的形式存在于内存中,而不是对象。它们不是Object的子类,不能参与面向对象的开发。在java1.5本版本以前一下的代码是得不到通过的
publicclass Test{
publicstatic void main(String[] args){
String str ="hello";
doSome(str);//可以,因为String是Object的子类
        int i =1;
//程序编译不通过,原因在于int不是Object的子类,不能使用多态性。
doSome(i);
}
publicstatic void doSome(Object o){
....
}
}
问题出现的原因就是基本类型int没有继承关系,它不是Object的子类。所以,若想让基本类型以对象的形式存在,我们就需要定义一个类Integer,然后用其实例来描述一个基本类型int。这样的好处在于,我们使用对象来描述基本类型数据,而类又是继承自Object的。从而可以让基本类型参与面向对象的开发。好在像Integer这样的类不需要我们定义,因为java已经提供了8中基本类型对应的包装类。
注:java1.5版本后出现了自动拆装箱特性,上述代码可以正常编译通过。自动拆装箱我们后面会详细描述。
2.1.1. 基本类型包装类

对于8个基本类型,java提供了他们相应的包装类:
基本类型 包装类
byte java.lang.Byte
short java.lang.Short
int java.lang.Integer
long java.lang.Long
float java.lang.Float
double java.lang.Double
char java.lang.Character
boolean java.lang.Boolean
其中除了Character与Boolean的父类是Object之外,其余的都是继承自:java.lang.Number
2.1.2. Number及其主要方法

上一节我们已经知道,除了Character与Boolean之外的其他包装类都是继承自Number的,这些包装类都有一个共性,描述的都是数字。那么我们来了解一下他们的父类:java.lang.Number
Number是一个抽象类。本身不能实例化。Number 的子类必须提供将表示的数值转换为 byte、double、float、int、long 和 short 的方法
比如:
abstract double doubleValue() 以double形式返回指定的数值
abstract int intValue() 以int形式返回指定的数值
abstract float floatValue() 以float形式返回指定的数值
剩下的抽象方法请参阅API文档:java.lang.Number
2.1.3. Integer.parsetInt()方法

java.lang.Integer是int的包装类,其每一个实例用于描述一个基本类型int的值。
Integer有一个静态方法static int parseInt(String s)
该方法的作用是将一个描述整数的字符串解析为该整数,并用int形式返回。该方法可能会抛出NumberFormatException异常:当给定的字符串里边含有非整数字符时。
2.1.4. Double.parseDouble()方法

java.lang.Double是double的包装类,其每一个实例用于描述一个基本类型double的值。
Double有一个静态方法static int parseDouble(String s)
该方法的作用是将一个描述小数的字符串解析为该小数,并用double形式返回。该方法可能会抛出NumberFormatException异常: 如果字符串不包含可解析的 double 值。
2.1.5. 包装类重写的toString()方法

所有的包装类都重写了toString()方法,它们都是通过String的valueOf()方法实现的。
publicStringtoString(){
returnString.valueOf(value);
}
对于String的valueOf()方法,我们在之前讲解String的课程中已经学习。
2.2. 自动装箱和拆箱

2.2.1. 自动装箱和拆箱的操作

现在我们来学习一下如何在基本类型与包装类之间相互转换。
当我们需要将基本类型转换为包装类时,我们可以调用包装类的一个静态方法valueOf():
Integer i = Integer.valueOf(1);
Double d = Double.valueOf(1.1):
当我们需要将包装类转换为基本类型时,我们可以使用包装类的方法xxxValue()方法(这里不同的包装类方法名不完全一致,但都是以Value结尾):
Integer i =newInteger(1);
int n = i.intValue();
Double d =newDouble(1.1);
double dn = d.doubleValue();
虽然我们可以通过上述的方法在基本类型与包装类之间相互转换。但是在实际编写代码时相对还是比较麻烦的。java在1.5版本后推出了一个新的特性:自动拆装箱。
一下代码在java1.4时编译不通过,但是在java1.5之后可以:
int i =newInteger(1);//可以自动将包装类转换为基本类型  自动拆箱
Integer in=1;//可以自动将基本类型转换为包装类  自动装箱
2.2.2. 自动装箱和拆箱的原理

通过上一节我们知道了如何在基本类型与包装类之间相互转换,也知道了java的自动拆装箱特性。那么java是如何实现的自动拆装箱呢?
事实上JVM不支持该特性,自动拆装箱只是编译器在编译过程中的"预处理"操作。编译器在看到需要在包装类与基本类型之间转换时,会在编译为字节码时进行改变:
源代码中 编译后的字节码中
Integer a = 100 =< Integer a = Integer.valueOf(100);
Integer b = 200 =< Integer b = Integer.valueOf(200);
Integer c = a+b =< Integer c = Integer.valueOf (a.intValue( ) + b.intValue( ));
double d = c =< double d = c . doubleValue( );




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2