包装类
1.为什么需要包装类?
Java在设计之初有一个基本原则:一切皆对象,一切的操作都要求用对象的形式进行描述。但是这里面就会出现一个矛盾,基本数据类型不是对象。那么我们会如何修复这个BUG呢?最简单的做法是将基本数据类型作为一个类的属性保存起来,这样就相当于把基本数据类型包装了一下.
实现基本数据类型的包装类
.
.
代码分析:
我们实现了基本数据类型转成Java对象的方式,Java中给我们提供了类似的实现类
包装类表格
.
我们观察上述的表格发现除了int->Integer,char->Character,其他的都是基本数据类型的首字母大写,很好记忆的.
但是以上给出的包装类又分为两种子类型:
对象型包装类(Object直接子类):Character、Boolean。
数值型包装类(Number直接子类):Byte、Short、Integer、Float、Double、Long。
Number是一个抽象类,里面一共定义了六个操作方法:intValue()、shortValue()、byteValue()、floatValue()、longValue()、doubleValue()。
2.装箱和拆箱
现在已经存在有基本数据类型与包装类,那么这两种变量间的转换就通过以下方式定义。
装箱操作:将基本数据类型变为包装类的形式。
每个包装类的构造方法都可以接收各自数据类型的变量。
拆箱操作:从包装类之中取出被包装的数据。
利用Number类中提供的一系列的:xxxValue()方法完成。
示例1-以int和Integer为例演示装箱和拆箱操作的过程
.
之前使用所编写的Int类,现在换成了Integer这个系统类。
示例2-以double和Double为例演示装箱和拆箱操作的过程
.
示例3-以boolean和Boolean为例演示装箱和拆箱操作的过程(不是Number子类)
.
现在可以发现,所有的包装类都使用了同样形式的方法进行操作。 在JDK1.5之前能够使用的操作都是以上形式的代码,但是JDK1.5之后,Java为了方便开发提供了自动装箱与自动拆箱的机制,并且可以直接利用包装类的对象进行数学计算。
示例4-以int和Integer为例观察自动装箱和自动拆箱操作的过程
.
示例5-以boolean和Boolean为例观察自动装箱和自动拆箱操作的过程(不是Number子类)
.
重点:正式因为Java提供了自动装箱和自动拆箱的机制,那么Object可以接收一切的数据类型(Object可以统一天下了)
转换流程:基本数据类型 自动装箱(成为对象) 向上转型为Object。
示例6-以Object接收int数据类型演示转换过程
.
“莫名其妙”的NullPointException
在我们开发过程中,碰到过不少因为请求参数或者接口定义字段设置为int(或者其他基本类型)而导致NullPointException(空指针异常)。代码大致地运行步骤如下所示,当然不会跟这个完全一样。
.
代码分析:
上面的代码可以编译通过,但是会抛出空指针异常(NullPointException)。
前面已经说过了,int b = a实际上是int b = a.intValue(),
3.==和equlas()
大家都应该清楚明了的了解两者的区别,
一句话说就是 == 比较的是内存中地址,equlas() 对比的为数值,因为基本类型相同的数值指向的同一块内存,所以可以用==来比较,而引用类型则不可以。
由于a的引用值为null,在空对象上调用方法就会抛出NullPointException。
.
代码分析:
obja == objb
不是应该比较内存地址吗?为什么能相等呢?我们需要解决这个问题,源码分析
在使用包装类的时候很少会利用构造方法完成,几乎都是直接赋值(这一点与String相同),但是在内容是否相等的时候,请一定要记住使用equals()方法。
两个包装类引用相等性
在Java中,“==”符号判断的内存地址所对应的值得相等性,具体来说,基本类型判断值是否相等,引用类型判断其指向的地址是否相等。看看下面的代码,两种类似的代码逻辑,但是得到截然不用的结果。
.
这个必须从源代码中才能找到答案。Integer类中的valueOf():
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i
代码分析:
由于127属于[-128, 127]集合范围内,所以valueOf()每次都会取出同一个Integer对象,故第一个“==”判断结果为true;而128不属于[-128, 127]集合范围内,所以valueOf()每次都会创建一个新的Integer对象,由于两个新创建的对象的地址不一样,故第一个“==”判断结果为false。
再次分析比较过程
.
4.数据类型转换(核心)
使用包装类最多的情况实际上是它的数据类型转换功能上,在包装类里面,最大的优点就是提供将String型数据变为基本数据类型的方法,使用几个代表的类做说明:
Integer类:public static int parseInt(String s)。
Double 类:public static double parseDouble(String s)。
Boolean类:public static boolean parseBoolean(String s)。
**特别注意:**Character类里面并不存在字符串变为字符的方法,因为String类有一个charAt()的方法可以根据索引取出字符内容,并且一个字符的长度才有一位。
范例1:将字符串变为int型数据
.
此时实现了字符串变为基本数据类型的操作。但是在这样的转换过程之中请一定要注意:被转换为数字的字符串一定要由数字所组成。如果不是数字组成,转换过程中会报异常:NumberFormatException
范例2:错误代码
.
.
范例3:将字符串变为double型数据
.
范例4:将字符串变为boolean型数据
.
范例5:将字符串变为boolean型数据
.
代码分析:
在Boolean进行转换的过程里面,如果要转换的字符串不是true或者是false,那么将统一按照false进行处理。
现在既然实现了字符串变为基本数据类型操作,那么也一定可以实现基本数据类型变为字符串的操作,对于此类操作有两种做法:
操作一:任何基本数据类型与字符串使用了“+”操作之后都表示变为字符串。
.
这样的操作虽然可以简单的完成,但是会存在有垃圾的问题。
操作二:public static String valueOf(数据类型 变量) 开发推荐
.
这样的转换不会产生垃圾,所以在开发时往往会使用以上做法。
5.小结
一定要清楚JDK1.5之后才提供有自动装箱与拆箱操作。
字符串与基本数据类型的互相转换:
字符串变为基本数据类型,依靠包装类的parseXxx()方法。
基本数据类型变为字符串,依靠String.valueOf(数据类型 变量)方法。
领取专属 10元无门槛券
私享最新 技术干货