八个基本类型:
- boolean/1
- byte/8 -2^7~2^7-1
- char/16 0~2^16-1
- short/16 -2^15~2^15-1
- int/32 -2^31~2^31-1
- float/32
- long/64 -2^63~2^63-1
- double/64
每个基本类型都有对应的包装类型,基本类型与其对应的包装类型之间的赋值使用自动装箱与拆箱完成。
Integer x = 2; // 装箱 int-->Integer int y = x; // 拆箱 Integer-->int
new Integer(num)与Integer.valueOf(num) 的区别在于,new Integer(num)每次都会新建一个对象,而Integer.valueOf(num)可能会使用缓存对象,导致多次使用Integer.valueOf(num)会取得同一个对象的引用。如以下代码所示:
Integer a = new Integer(127); Integer b = new Integer(127); Integer c = 127; Integer d = 127; Integer e = 128; Integer g = 128; System.out.println(a == b); //false 不同对象,当然不同地址 System.out.println(a == c); //false 不同存储地方,一个常量池,一个堆,当然不同地址 System.out.println(c == d); //true 都在常量池,且127在-128~127之间,所以引用已有的对象,无需new System.out.println(e == g); //false 128不在-128~127之间,相当于在堆中new两个Integer对象
参照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
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; }
因此,当num值在-127~128之间时,创建Integer对象时先查看缓存池中是否存在num值,如果没有就在缓存池中新建,有则直接使用;若num不在-127~128之间时,valueOf使用new Integer(num)方式在堆中新建对象。
Java 还将一些其它基本类型的值放在缓冲池中,包含以下这些:
- boolean values true and false
- all byte values
- short values between -128 and 127
- int values between -128 and 127
- char in the range \u0000 to \u007F
因此在使用这些基本类型对应的包装类型时,就可以直接使用缓冲池中的对象。