【实践】java.lang.Integer源码分析 -- valueOf
来源:互联网 发布:mac管理员名称是什么 编辑:程序博客网 时间:2024/05/17 02:15
public static Integer valueOf(String s, int radix) throws NumberFormatException { return Integer.valueOf(parseInt(s,radix));}public static Integer valueOf(String s) throws NumberFormatException { return Integer.valueOf(parseInt(s, 10));}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);}
Integer实现了三种valueOf
方法(一个底层实现,两个重载),valueOf(String s, int radix)
和 valueOf(String s)
都是优先调用parseInt(s,radix)
,无非就是十进制解析或者其它进制解析返回响应int数值,关于parseInt方法分析见另一篇博文:传送门
其实最终的调用都是valueOf(int i)
方法。我们看到方法第一行是断言一个IntegerCache
类的high
属性大于等于127。我们先跳过IntegerCache
相关这段,看最终的返回return new Integer(i);
我们之前看到Integer(int value)
构造方法其实就是将成员变量(属性property)value
设置为传入值。
现在我们回到IntegerCache
,从语义上看这段代码的意思大概是,当传入int值位于IntegerCache
的成员变量low
和high
之间时,直接返回IntegerCache.cache[i + (-IntegerCache.low)]
:
private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { int 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); h = 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() {}}
其实IntegerCache
是Integer的一个私有静态内部类,它声明了三个静态不可变成员变量,int类型low
与high
,Integer类型cache
数组,low初始化为-128。然后其核心是一个static
静态块。
我们依然先跳过integerCacheHighPropValue
相关这段,那么代码如下:
int h = 127;high = h;cache = new Integer[(high - low) + 1];int j = low;for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++);
先初始化high = 127;
然后初始化cache为high - low + 1
大小的Integer数组,也就是cache的大小为low~high的跨度+1,为什么这里不用127 - (-128) + 1 = 256,因为我们还没考虑integerCacheHighPropValue
,从上面的代码可以看到h也可能是其它值。接下来,初始化一个int变量j,它的值是low = -128
,接着开始在high - low + 1
范围大小内循环遍历,依次为cache[k]赋值,从等式来看,cache最终也就是-128 ~ 127(h=127情况),意思说Integer将-128 ~ 127缓存下来了。
这时我们回到integerCacheHighPropValue
也就容易明白了。Integer缓存的数值范围上限提供了自定义配置方式,只是如果这个上限小于127的情况,它主动帮你调优为127,如果大于127的情况,那它保证你的上限值不超过int类型最大值。
现在我们再回到valueOf(int i)
方法,当我们想要将一个int数值转为Integer类时,如果int参数值在Integer缓存中,那么直接返回与该int参数值对应的缓存Integer对象,也就省去了Integer对象创建的开销。
我们小结一下,当我们想将int转Integer时,Integer缓存了-128 ~ 127数值,为之后的频繁调用节省了对象创建的开销,因为-128 ~ 127可能是我们最常用的数值。也因此有一个有趣的问题:
Integer integer1 = 1;Integer integer2 = 1;Integer integer3 = -129;Integer integer4 = -129;Integer integer5 = 128;Integer integer6 = 128;System.out.println(integer1 == integer2);System.out.println(integer3 == integer4);System.out.println(integer5 == integer6);
打印如下:
truefalsefalse
很显然符合我们上述Integer缓存策略,1是缓存范围内,所以返回了同一个对象实例,而-129和128刚好超出了缓存范围,所以返回的是new Integer(int i)
两个不同的对象实例。
当然,在判断两个Integer对象是否相等情况,我们期望的是value
值相等,还是使用equals
方法。
- 【实践】java.lang.Integer源码分析 -- valueOf
- 【实践】java.lang.Integer源码分析
- 【实践】java.lang.Integer源码分析 -- parseInt
- java.lang.Integer源码分析
- String.valueOf Long.valueOf Integer.valueOf 源码分析 缓存
- java Integer.valueOf()方法
- java Integer.valueOf()方法
- java Integer.valueOf()方法
- java Integer.valueOf()方法
- java Integer.valueOf()方法
- java Integer.valueOf()方法
- java Integer.valueOf()方法
- java Integer.valueOf()方法
- Integer.valueOf()方法 java
- Java-Integer源码分析
- 由java.lang.Integer中Integer valueOf(int i)产生的问题
- java.lang.Enum.valueOf()
- 【Java】Integer.parseInt() & Integer.valueOf() & new Integer()
- Spring基础(一):对Spring一无所知的童鞋请进!!!
- bzoj1222(dp)
- some function about Date
- 栈的实现
- Java并发编程:阻塞队列
- 【实践】java.lang.Integer源码分析 -- valueOf
- 注册那些事儿—交互设计总结
- 微软将重新崛起
- Android Universal-Image-Loader 解析
- Android BitmapDrawable使用场景
- 短信验证接口0818
- 在ScrollView中ListView或者类似的组件只显示一列的问题
- dex2oat程序参数总结
- MP4文件sample读取流程