Java有八种基本数据类型,为了面向对象的严谨性,Java对这八种基本数据类型作了封装,衍生出了八个基本数据类型封装类:
byte(字节) –> Byte
shot(短整型) –> Shot
int(整型) –> Integer
long(长整型) –> Long
float(浮点型) –> Float
double(双精度) –> Double
char(字符型) –> Char
boolean(布尔型) –> Boolean
在使用过程中,封装类必然与原基本数据类型有所差异,并且有时使用不当会产生一些问题,以java.lang.Integer为例,我们一起来分析它们的封装设计想法与应用实践。
打开java.lang.Integer的源码(.java),映入眼帘的是
public final class Integer extends Number implements Comparable<Integer>
Integer是final的,也就是说Integer类不能被继承,没有子类,Integer中所有方法都是final的。其次Integer继承了抽象类Number
并实现了Comparable<Integer>
接口。
Comparable<Integer>
相信大家并不陌生,读者可自行某du或某gle。其实就是实现了int compareTo(T o)
方法,Integer的实现也很简洁易懂:
public int compareTo(Integer anotherInteger) {
return compare(this.value, anotherInteger.value);
}
public static int compare(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
所以我们在比较两个Integer封装类的时候,其实比较的是它们的value
值。value
其实就是一个int类型的成员变量(属性property):
private final int value;
从声明来看,value
对外是不可见的,并且只能被赋值一次。我们可以看到Integer的构造函数只有两个:
public Integer(int value) {
this.value = value;
}
public Integer(String s) throws NumberFormatException {
this.value = parseInt(s, 10);
}
一个是直接传入一个int参数为value值,另一个是传入String字符串,转换为int类型value,如果无法转换会抛出NumberFormatException
parseInt方法解析:传送门
我们回到Integer类的声明,除了实现Comparable<Integer>
接口,还继承了Number
抽象类。
public abstract class Number implements java.io.Serializable {
public abstract int intValue();
public abstract long longValue();
public abstract float floatValue();
public abstract double doubleValue();
public byte byteValue() {
return (byte)intValue();
}
public short shortValue() {
return (short)intValue();
}
}
我们看到Number
是可序列化的抽象类,并且提供了int,long,float,double数值获取的抽象方法,以及byte,short数值获取的方法实现。这里其实就是java的多态,运行时才知道Number
的实例类型,调用具体的取值方法。
而Integer在重写这些方法时,除了int取值返回value
本身外,其它直接强制转换。
最后我们再了解下Integer中另一个常用的方法valueOf:传送门
针对Integer分析暂时到这,有兴趣的读者还可以自行深入研究,这里套用别人一句话结尾:
与其听信谣言,不如自我实践。