抽象类Number是BigDecimal, BigInteger,Byte,Double,Float,Integer, Long, Short类的父类,实现了java.io.Serializable接口,这个接口以后再说。其中的抽象方法主要是基本数据类型的转换,这些方法都可能涉及到四舍五入和截断
Integer类
实现了父类的抽象方法,利用的机制是强制类型转换。
- 成员变量
public static final int MIN_VALUE = 0x80000000;
public static final int MAX_VALUE = 0x7fffffff;
最大值和最小值,大小都是32位int的最大值和最小值
public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int");
类实例的基本类型
final static char[] digits = {'0' , '1' , '2' , '3' , '4' , '5' ,'6' , '7' , '8' , '9' , 'a' , 'b' ,'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,'o' , 'p' , 'q' , 'r' , 's' , 't' ,'u' , 'v' , 'w' , 'x' , 'y' , 'z'};
所有可能的字母,在数字转String的时候用到
final static char [] DigitTens = {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0','1', '1', '1', '1', '1', '1', '1', '1', '1', '1','2', '2', '2', '2', '2', '2', '2', '2', '2', '2','3', '3', '3', '3', '3', '3', '3', '3', '3', '3','4', '4', '4', '4', '4', '4', '4', '4', '4', '4','5', '5', '5', '5', '5', '5', '5', '5', '5', '5','6', '6', '6', '6', '6', '6', '6', '6', '6', '6','7', '7', '7', '7', '7', '7', '7', '7', '7', '7','8', '8', '8', '8', '8', '8', '8', '8', '8', '8','9', '9', '9', '9', '9', '9', '9', '9', '9', '9',} ;final static char [] DigitOnes = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9','0', '1', '2', '3', '4', '5', '6', '7', '8', '9','0', '1', '2', '3', '4', '5', '6', '7', '8', '9','0', '1', '2', '3', '4', '5', '6', '7', '8', '9','0', '1', '2', '3', '4', '5', '6', '7', '8', '9','0', '1', '2', '3', '4', '5', '6', '7', '8', '9','0', '1', '2', '3', '4', '5', '6', '7', '8', '9','0', '1', '2', '3', '4', '5', '6', '7', '8', '9','0', '1', '2', '3', '4', '5', '6', '7', '8', '9','0', '1', '2', '3', '4', '5', '6', '7', '8', '9',} ;
这两组变量是String转数字的时候使用,当数字大于65536时,一次转换两位数字,DigitTens 是十位数,DigitOnes 是个位数
final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,99999999, 999999999, Integer.MAX_VALUE };
此变量是用于判断数字的位数,当小于等于sizeTable[i]时,位数为i+1
private final int value;
类实例中存储数据的成员变量
public static final int SIZE = 32;
记录了最长位数的Integer
- 构造函数
有两个构造函数,分别是:
public Integer(int value) {this.value = value;
}
参数为一个int,赋值给value,另一个构造函数为
public Integer(String s) throws NumberFormatException {this.value = parseInt(s, 10);}
参数为String,调用本类中的parseInt以默认10进制的方式解析成int类型数据,再赋值。
- 其他函数
public static int parseInt(String s, int radix)throws NumberFormatException
{...return negative ? result : -result;
}public static int parseInt(String s) throws NumberFormatException {return parseInt(s,10);
}
参数有两个,s:被解析的字符串,radix:进制(默认是10进制)。排除掉所有的异常后,实现的细节是先取得字符转是否有负号,遍历字符串,得到result,最后加上负号。
public static String toString(int i, int radix) {...if (radix == 10) {return toString(i);}...return new String(buf, charPos, (33 - charPos));
}
public static String toString(int i) {...return new String(buf, true);
}
public String toString() {return toString(value);
}
转字符串的函数,传入的参数还是有进制,当进制为10时,调用另一个重载函数,无参数的函数返回的是value的10进制形式。
private static class IntegerCache {static final int low = -128;static final int high;static final Integer cache[];static {// high value may be configured by propertyint h = 127;String integerCacheHighPropValue =sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");if (integerCacheHighPropValue != null) {int i = parseInt(integerCacheHighPropValue);i = Math.max(i, 127);// Maximum array size is Integer.MAX_VALUEh = Math.min(i, Integer.MAX_VALUE - (-low) -1);}high = h;cache = new Integer[(high - low) + 1];int j = low;for(int k = 0; k < cache.length; k++)cache[k] = new Integer(j++);}private IntegerCache() {}}
有一个静态嵌套类,定义的是一个缓存,默认值为[-128,127],可以通过设置JVM的参数修改这个缓存区间的最大值,缓存中会提前新建好数组存储缓存区间的对象。在进行解码String的时候,是调用了缓存的,除此之外,什么地方还用到了这个缓存呢?
当我们直接使用整数创建Integer对象时,调用的是valueOf函数,如下
Integer a = 100;//调用valueOf函数创建对象,可以反汇编、设断点去看
public final class Integer extends Number{public static Integer valueOf(int i) {assert IntegerCache.high >= 127;if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i);}
}
当a的值在缓存区间的时候,那么直接返回缓存的对象,而且下次定义b也等于100的话,a==b的结果是true,因为使用的是同一个对象,如果a和b的值在缓存区间外的话,a==b的结果是false,当然可以通过JVM的参数,设置这个缓存区间。
Short类、Byte类、Long类
都跟Integer很像,其中不少方法也是借鉴了Integer类中的方法去实现,其中一个比较重要的点是,他们中的缓存是固定长度的,是直接写死的。
Float类、Double类
与之前的实现细节是一样的,只是多了很多对浮点的处理
阅读源码为JDK1.7