深入源码分析Integer类
Java中的包装类与基本类型一一对应,为了让你拥有面向对象的特点,方便来同一管理,所以就创造了基本类型的包装类,属于引用类型,并且可以实现自动拆装箱,实现基本类型和包装类的自动转换,其中Integer类的源码很值得深入分析和思考学习。
Integer类的关键源码
- 包装类都继承了Number 抽象类,并且Number抽象类实现了序列化接口,说明是可序列化的
- 实现了接口Comparable,即实现了compareTo方法
- 重写了hashCode和equals方法,其中hashCode是value,而equals只是比较同种类型的intValue方法返回的值,intValue的返回值也是value
Short、Byte、Long、Integer
包装类中都含有一个对应的内部缓存类
,区间都在[-128,127],缓存上界限,可以通过JVM属性来配置,默认为127,用于建立在此区间的数值的缓存,初始化数组将一定范围的整数放到cache数组中,然后在调valueOf
方法的时候首先判断范围然后从缓存数组中去抓取数据 ,提高效率valueOf()
这个方法去创建Integer对象,Integer a = 100;
这样的也是走的这个方法,这样就会先从缓存中获取对象;以new的方式创建对象,每个对象的内存值都不一样,在堆中重新分配内存
1 | public final class Integer extends Number implements Comparable<Integer> { |
hashCode、equals和compareTo方法
1 | public int compareTo(Integer anotherInteger) { |
parseInt方法
1 | //没有指定进制的,默认为10进制的字符串,经常使用的静态方法 |
1 |
|
IntegerCache内部缓存类
Short、Byte、Long、Integer
包装类中都含有一个对应的内部缓存类
,区间都在[-128,127],缓存上界限,可以通过JVM属性来配置,默认为127,用于建立在此区间的数值的缓存,初始化数组将一定范围的整数放到cache数组中,然后在调valueOf
方法的时候首先判断范围然后从缓存数组中去抓取数据 ,提高效率。
推荐使用valueOf()
这个方法去创建Integer对象,Integer a = 100;
这样的也是走的这个方法,这样就会先从缓存中获取对象。
1 | //巧妙设计的缓存内部类 |
使用Integer创建对象时常见问题
1 | Integer a1 = 100; |
因为Integer的缓存机制,缓存了[-128,127],这些可以直接取出;
超过了缓存的那个范围,就建了个新对象,内存值不一样,返回false
以new的方式创建对象,每个对象的内存值都不一样,在堆中重新分配内存
toString(int i, int radix)方法
1 | //该方法使用到的字典 |
toString(int i)方法
把int型包装成Integer然后再转化成String字符串
其中的细节难理解点:
q = (i * 52429) >>> (16+3); // 实质是和i/10效果一致,但是为什么要这样写呢?
因为2<<(16+3)=2<<19=524288,
(i 52429)>>>(16+3) = i \52429/524288=52429.0/524288=0.1000003814697….6位的精度已经足够多了,所以就是i*0.1=i/10,此处这样设计是为了提高精度
1 | public static String toString(int i) { |