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
	}
}

文中作者提到,包装类的“”运算在不遇到算术运算的情况下不会自动拆箱。
对于为何 c
d 为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

posted @ 2017-06-28 13:58  江湖小_虾  阅读(314)  评论(0)    收藏  举报