package review.base.Java那些事儿;
public class 一_让人疑惑的Java代码{
public static void main(String[] args){
TestNumberCache tnc = new TestNumberCache();
tnc.numberTest();
}
}
class TestNumberCache{
public void numberTest(){
Integer i1 = 100;
Integer i2 = 100;
System.out.println("Integer100: " + (i1==i2));
Integer i3 = 1000;
Integer i4 = 1000;
System.out.println("Integer1000: " + (i3==i4));
/**
* 参考文章来自:https://zhuanlan.zhihu.com/p/27562748
*
* 通过输出可以看到,结果是:
* true
* false
*
* 不是包装对象不能用==么,不是==比较的是对象的地址么。
* 通过反编译,我们可以看到代码会被编译成:
* Integer i1 = Integer.valueOf(100);
* Integer i2 = Integer.valueOf(100);
* System.out.println(i1==i2);
*
* Integer i3 = Integer.valueOf(1000);
* Integer i4 = Integer.valueOf(1000);
* System.out.println(i3==i4);
*
*
* 直接去valueOf源码查看:
*
* 原来这里存在一个缓存。如果是在-128到127之间的数字,会存在一个名为cache的Integer数组中。再次用到会直接返回。而其他情况,则是直接new Integer(i)。
* 而事实上:
* Java的包装类大都有这种机制,即Byte,Short,Integer,Long,Character,Boolean。名叫常量池。
* 而Double、Short并没有。
*
*/
// 给一个源码入口,直接进去追一下就明白了
Integer integerNumber = Integer.valueOf(128); // cache -128 ~ 127
Long longNumber = Long.valueOf(100); // cache -128 ~ 127
Short shortNumber = Short.valueOf("100"); // cache -128 ~ 127
Double doubleNumber = Double.valueOf(100.1); // 直接 new Double(d)
Float floatNumber = Float.valueOf(100.1f); // 直接 new Float(f). 这里仔细观察,带了一个f。说明,默认的带小数点的数字类型为double。除非后面尾随一个f表名是float。
Integer integerNumber2 = 128;
Long longNumber2 = 100l;
Short shortNumber2 = 100;
Double doubleNumber2 = 100.1;
Float floatNumber2 = 100.1f;
//对比
System.out.println("-----------对比-----------");
System.out.println("Integer128: " + (integerNumber==integerNumber2));
System.out.println("Long100: " + (longNumber==longNumber2));
System.out.println("Short100: " + (shortNumber==shortNumber2));
System.out.println("Double100.1: " + (doubleNumber==doubleNumber2));
System.out.println("Float100.1: " + (floatNumber==floatNumber2));
}
}