java中==和equals的区别
在看深入理解java虚拟机时,作者在讲java语法糖的时候,举了例子比较java中==和equals的区别,代码如下
public class GenericTypes {
public static void main(String[] args) {
/**
* 鉴于包装类的“==”运算在不遇到算术运算的情况下不会自动拆箱,以及它们equals()方法不处
理数据转型的关系
*/
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321; //自动装箱为Integer
Integer f = 321; //自动装箱为Integer
Long g = 3L; //自动装箱为Long
List<Integer> aIntegers = Arrays.asList(1,2,3,4);
System.out.println(c == d); //true
System.out.println(e == f); //false
System.out.println(c == (a + b)); //true
System.out.println(c.equals(a + b)); //true
System.out.println(g == (a + b)); // true //全部都拆箱变为基本类型,基本类型都缓存起来的
System.out.println(g.equals(a + b)); //false
}
}
文中作者提到,包装类的“”运算在不遇到算术运算的情况下不会自动拆箱。
对于为何 cd 为true, 而ef为false,原因是因为,在自动装箱时,因为原本Integer就已经缓存了-128~127的值,因此在自动装箱时,直接拿到常量池中缓存好的值的地址,因此 c d, 而e和f为321 > 127 所以就等于新增对象,因此为false
对于 c == (a + b) 为true ,反编译源码看到,
18: aload_3
19: invokevirtual #4 // Method java/lang/Integer.intValue:()I
22: aload_1
23: invokevirtual #4 // Method java/lang/Integer.intValue:()I
26: aload_2
27: invokevirtual #4 // Method java/lang/Integer.intValue:()I
,全部都拆箱为基本数据类型来比较,因此为true
对于c.equals(a + b) 为true,a + b 会自动拆箱变为基本类型, 但是在比较的时候又会自动装箱,equals比较值
对于g == (a + b)为true ,根据反编译源码看来 ,全部都拆箱为基本数据类型进行比较 ,因此为true
最后一个为何为false ,Long 和Integer 调用equals 为false

浙公网安备 33010602011771号