▮题目
•请问如下代码打印什么?
public class Main { public static void main(String[] args) { Integer a = 1; Integer b = 1; System.out.println(a == b); } }
•又请问如下代码打印什么?
public class Main { public static void main(String[] args) { Integer a = 200; Integer b = 200; System.out.println(a == b); } }
•答案
前者为“true”,后者为“false”
▮解析
▪得到一个包装类对象
/* Java原码 */ public static Integer valueOf(int i) { //i在[-128,127]中返回一个已有的Integer对象 if (i >= IntegerCache.low(-128) && i <= IntegerCache.high(127)) //(-128)是我自行添加的 return IntegerCache.cache[i + (-IntegerCache.low)]; //i不在[-128,127]时,new一个新的Integer对象返回 return new Integer(i); }
“ valueOf()”是用来创建包装类对象的方法。根据原码可以看到,[-128,127]范围类的对象不是新建的,在这范围之外才会去new出一个新对象。
•IntegerCache
翻译一下就是“整形缓存”,它是包装类里的静态内部类。它里面有一个静态数组成员Integer [ ] cache,存放了范围[-128,127]内所有的Integer对象。
只要在这个范围里,新建的Integer引用便会指向这个缓存里的对象。这些引用共用着[-128,127]里的对象,以此来实现代码复用。这种模式也称为“享元模式”,即共用一个对象。
•IntegerCache.cache[i + (-IntegerCache.low)]
IntegerCache.cache[i + (-IntegerCache.low)(--128 -> 128)]
因为数组的下标是从0开始的,所以范围为[-128,-1]的对象只能存放在cache[0~127]中。所以通过cache[i+128]得到与i同值的Integer对象。
▪“==”比较的是对象地址
因为在【-128,127】的范围内,所有同值Integer引用都指向同一个对象,所以用“==”会得到“ true ”。但在这个范围之外,a,b的对象地址就不再相同,所以得到了“ false ”。因此,我们应该用“ equals() ”来比较两个包装类是否相同,而不是“==”。
▮扩展:“>,<”比较的是对象的value
“==”比较的是对象的地址,那“>,<”比较的是什么?
对此,各位可以自己去写代码来测试测试,最终你会发现,“>,<”比较的是对象的value,而不是对象的地址。
•代码实例
public class Main { public static void main(String[] args) { Integer a = 200; Integer b = 200; Integer c = 201; Integer d = 199; System.out.println(a > b); System.out.println(c > b); System.out.println(d < b); } }
•运行截图