一、包装类
Java 面向对象编程,一切都是对象,但是有例外: 8 个基本数据类型不是对象,因此在很多时候非常不方便。 为此, Java提供为 8 个基本类型提供了对应的包装类:
- byte ------- Byte
- short ------ Short
- int ---------- Integer
- long -------- Long
- char -------- Character
- float -------- Float
- double ----- Double
- boolean----- Boolean
包装类如何使用? JDK1.5 , 新增了 2 个功能:自动装箱、自动拆箱。
Integer x = 2; //装箱 调用了 Integer.valueOf(2)
int y = x; //拆箱 调用了 x.intValue()
自动装箱 ----- 基本类型的值 → 包装类的实例
自动拆箱 ----- 基本类型的值 ← 包装类的实例
二、缓存池
new Integer(123) 与 Integer.valueOf(123) 的区别在于:
- new Integer(123) 每次会新建一个对象;
- Integer.valueOf(123) 会优先使用缓存池中的对象,引用的是同一个对象
Integer x = new Integer(123);
Integer y = new Integer(123);
System.out.println(x == y); //false --不同对象
Integer z = Integer.valueOf(123);
Integer k = Integer.valueOf(123);
System.out.println(z == k); //true --相同对象
结果为:
由此可知 .valueOf() 方法返回了缓存池中的对象,源码如下:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)]; //直接返回缓存池中的对象
return new Integer(i);
}
Integer 的缓存池默认大小为 -128 ~ 127,源码如下
private static class IntegerCache {
static final int low = -128; //下界
static final int high;
static final Integer cache[]; //缓存池数组
static {
// high value may be configured by property
int h = 127; //默认上界
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); //系统属性修改上界
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127); //获取上界
// Maximum array size is Integer.MAX_VALUE
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;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
在Java 8 中基本类型对应的缓冲池如下:
- Int,short -128 ~ 127
- all byte
- char \u0000 to \u007F Unicode编码对照
在使用这些基本类型对应的包装类型时,如果该数值范围在缓存池范围内,就可以直接使用缓冲池中的对象。
在 JDK1.8 所有的数值类缓存池中,Integer的缓存池 IntegerCache 很特殊,他的下界是 -128,上界默认是 127,但是这个上界是可调的,在启动 JVM 的时候,通过 -XX:AutoBoxCacheMax = 来指定这个缓存池的大小,该选项在 JVM 初始化的时候会设定一个名为 java.lang.IntegerCache.high 系统属性,然后 IntegerCache 初始化的时候就会读取该系统属性来决定上界。