public static void main(String[] args) {
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 128;
Integer e = 128;
Long f = 3L;
Boolean i1 = false;
Boolean i2 = false;
#1. System.out.println(c==(a+b));//true
#2. System.out.println(c.equals(a+b));//true
#3. System.out.println(d==e);//false
#4. System.out.println(d.equals(e));//true
#5. System.out.println(f==(a+b));//true
#6. System.out.println(f.equals(a+b));//false
#7. System.out.println(i1==i2);//true
#8. System.out.println(i1.equals(i2));//true
}
- 1.当 “==”运算符的两个操作数都是包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)。所以“c==(a+b)”比较的是数值,而不是地址,则返回true;
2.包装类重写了equals()方法,源码是这样的:(以Integer为例)
public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; }
源码中可以看出,先比较是否是同一类型,如果是,则拆箱比较数值,否则,则返回false。所以,“c.equals(a+b)”返回true;
3.“d==e”返回false。首先在“Integer d = 128;”这里,发生了自动装箱,也就是调用了Integer.valueOf(128),但是查看源码可知,如果传入的int值在【-128,127】之间,会直接取缓存中对象返回,否则,创建新的对象返回。所以,由于这里128超出了缓存范围,则返回的是新创建的对象,如果d和e为 3,那么会返回true。
注意:
Integer、Short、Byte、Character、Long这几个类都会生成【-128,127】的缓存,所以valueOf方法都会取缓存中的值。而Double、Float不会生成缓存,所以每次valueOf()生成的是新对象,所以“==”比较两个Double或Float时,总会返回false;4.d.equals(e),先比较类型,一样,在比较数值,一样,则返回true;
5.“f==(a+b)”,虽然f为Long类型,但由于算术运算“+”发生自动拆箱,比较数值(同上面1),所以返回true;
- 6.“f.equals(a+b)”,“a+b”仍然是Integer类型,所以Long类型的equals()方法比较“a+b”不是Long类型,自然返回false;
7.Boolean i1 = false,自动装箱,调用valueOf(),源码如下
public static Boolean valueOf(boolean b) { return (b ? TRUE : FALSE); }
返回的是TRUE或FALSE,TRUE和FALSE是什么呢,源码:
public static final Boolean TRUE = new Boolean(true); public static final Boolean FALSE = new Boolean(false);
原来这两个是Boolean早已经创好的两个对象,相当于Integer中的缓存,所以,i1和i2返回的都是相同的对象,所以true;