Integer.valueOf(…)
valueOf(String s, int radix)
public static Integer valueOf(String s, int radix) throws NumberFormatException {
// 以 radix 进制。
return Integer.valueOf(parseInt(s,radix));
}
valueOf(String s)
public static Integer valueOf(String s) throws NumberFormatException {
// 1. 调用静态方法 parseInt() 将 s 以十进制转为 int 类型。
// 2. 调用 valueOf(int i) 将 1 的结果转为 Integer。
return Integer.valueOf(parseInt(s, 10));
}
valueOf(int i) - 重点
public static Integer valueOf(int i) {
// 判断所要转换的 i 是否在缓冲池当中。
if (i >= IntegerCache.low && i <= IntegerCache.high)
// 如果存在,则之间将缓冲池中的对象的引用返回。
return IntegerCache.cache[i + (-IntegerCache.low)];
// 如果不存在,则新建一个对象,返回新建对象的引用。
return new Integer(i);
}
IntegerCache
private static class IntegerCache {
static final int low = -128;
static final int high;
// 声明一个 final 的缓存区间。
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
// sun.misc.VM.getSavedProperty() 获取 Integer 所设置的缓存池大小。
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
// 将 integerCacheHighPropValue 转为 int 类型。
int i = parseInt(integerCacheHighPropValue);
// 获取 i 和 127 之间的最大值。
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
// public static final int MAX_VALUE = 0x7fffffff = 2,147,483,647 int 类型的最大值。
/*
* 为什么 MAX_VALUE 需要 -(-low) - 1 ?
* 1. 缓冲区的大小只能设置上限 high,不能设置下限 low。
* 2. i 为系统设置的缓冲区的上限,而不是缓冲区大小,默认为 127。
* 1. 缓冲区大小为:high - low + 1。
* 3. MAX_VALUE 需要减去 low 和 1 之后才是缓冲区的上限,减去之前是缓冲区的最大容量。
* 4. 所以是将最大上限和系统设置的上限比较,取较小者。
*/
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// 数字格式异常
// If the property cannot be parsed into an int, ignore it.
}
}
high = h; // 如果没有手动设置缓存区的大小,则 high = 127;
/********************************************************************************
* 以下分析均假设为:没有手动设置缓存区的大小:
********************************************************************************/
// 指定缓存数组 cache 的大小:127 - (-128) + 1 = 256
cache = new Integer[(high - low) + 1];
int j = low;
// 初始化 cache 数组,将 -128 , 127 保存到 cache 数组中。
// cache.length == 256
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// 索引:值 0:-128 1:-127 127:-1 128:0 129:1 255:127
// range [-128, 127] must be interned (JLS7 5.1.7)
// assert:断言,这个关键字可以判断布尔值的结果是否和预期的一样,
// 如果一样就正常执行,否则会抛出 AssertionError。
assert IntegerCache.high >= 127;
}
// 私有构造方法:证明 IntegerCache 此类不希望被其他类所使用。
private IntegerCache() {}
}
总结
-
IntegerCache
是Integer
类中的私有
静态
内部
类。 -
IntegerCache
相当于一个缓存,内部定义了一个缓冲区cache
,存储Integer
类型对象的引用,默认区间为 [-128, 127],可手动设置上限,但不可设置下线。 -
valueOf(int i)
:- 先判断参数
i
是否在缓冲区间内: - 如果在,则从
IntegerCache
中直接返回缓冲区中对于对象的引用。 - 如果不在,则新建一个对象,并返回引用。
- 先判断参数
Integer 对象比较问题
public static void main(String args[]) {
Integer a1 = 127;
Integer a2 = 127;
System.out.println(a1 == a2); // true
Integer b1 = 128;
Integer b2 = 128;
System.out.println(b1 == b2); // false
}
a1
a2
在[-128, 127]
范围内,所以指向缓冲区中同一个对象。b1
b2
不在[-128, 127]
范围内,所以,分别指向不同的对象。
建议使用
equals
进行对象之间的比较。