看代码:
public void testInteger(){ Integer a = 1; Integer b = 1; Integer c = 128; Integer d = 128; System.out.println(a == b); System.out.println(c == d);}
结果是什么?
答案是
true
false
这里先明确一个概念,对象之间的直等(==)比较的是两个内存的地址。而boolean byte char short int long float double八大基础类型比较的是值,即true==false,3==6这样比较的。
那么,int的包装类型Integer对象为什么有的相等,有的不相等?
且看Integer.java源码是怎么写的
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 a = 5;这样的赋值方式的时候,编译器会使用Integer中的valueOf方法自动装箱。
看上边代码第三行,数值i会与IntegerCache.low和IntegerCache.high进行比较。如果在这两个值之间,则返回一个已经存在的对象。
那么,我们顺着这条路走下去
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) { 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); } 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() {}}
Integer类中包含了一个内部类,这个内部类定义了low和high ,看最下边。
cache是一个Integer数组,包含了-128到大于127的int的包装对象。
也就是说,对象之间比较的确是内存的比较,只不过这里有一个坑,Integer保留了一个小范围空间的缓存对象数组,这样如果在小范围的使用Integr对象,就不需要频繁的开辟内存。
Boolean类默认也保存了true和false对象数组。
Byte256个对象全部保存
Short和Long范围和Integer范围相同。
坑:
在进行包含<,>的比较中,基本类型的包装对象会自动进行拆箱。
在switch语句中,包装对象也会进行自动拆箱,所以不会出现大数值比较不同的情况
String类型在switch语句中经过编译后会通过equals方法实现,所以也不会出现两个相同的字符串不相等的情况。
更多文章: