Java中基本类型都有对应的包装类分别有:Byte
、Short
、Integer
、Long
、Float
、Double
、Character
、Boolean
。而它们大部分都用到了缓存机制来提升性能。Byte
,Short
,Integer
,Long
这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据,Character
创建了数值在 [0,127] 范围的缓存数据,Boolean
直接返回 True
or False
。
Integer缓存源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| 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) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); assert IntegerCache.high >= 127; } private IntegerCache() {} } public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| private static class CharacterCache { private CharacterCache(){} static final Character cache[] = new Character[127 + 1]; static { for (int i = 0; i < cache.length; i++) cache[i] = new Character((char)i); } } public static Character valueOf(char c) { if (c <= 127) { return CharacterCache.cache[(int)c]; } return new Character(c); }
|
Boolean缓存源码
1 2 3
| public static Boolean valueOf(boolean b) { return (b ? TRUE : FALSE); }
|
由源码可见,超出范围了仍然会创建对象,缓存的范围区间的大小只是在性能和资源之间的权衡。
Float
、Double
没有缓存机制
举例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| Integer i1 = 33; Integer i2 = 33;
System.out.println(i1 == i2); Float i11 = 333f; Float i22 = 333f;
System.out.println(i11 == i22); Double i3 = 1.2; Double i4 = 1.2;
System.out.println(i3 == i4); Integer i5 = 127; Integer i6 = new Integer(127);
System.out.println(i5 == i6); Integer i7 = 128; Integer i8 = new Integer(128); Integer i9 = 128; System.out.println(i7 == i8);
System.out.println(i7 == i9);
|
谨记: 所有包装类型之间的值比较,尽量都要用equals
参考链接:
Java Guide 包装类型的缓存机制了解么?