Java 引用对象 == 和equals及内存分布

直接上代码

public class Four {  
	
    long width;  
    
    public Four(long l) {   
        width = l;  
    }  
    
    public static void main(String arg[]) {   
        Four a, b, c;  
        a = new Four(42L);   
        b = new Four(42L);   
        c = b;   
        long s = 42L;
        System.out.println("1."+(a==b));
        System.out.println("2."+(a==c));
        System.out.println("3."+(a==s));
        System.out.println("4."+(b==c));
        System.out.println("5."+(b==s));
        System.out.println("6."+(c==s));
        
    }
}

看看 123456 的值分别是什么。

我来给大家分析一波
首先先看变量 s ,他是基本数据数据类型,是不能直接和引用数据类型进行比较的。所以 3、5、6执行报错。
其次再分析对象 a,b,c,这里我画个图来大致描述一下内存情况

a 对象使用 new 关键字在堆内存中生成一个新对象
b 和 a 同样在内存中生成一个新对象
而 c 对象使用赋值符号将 b 的堆内存地址赋值给了 c ,所以 b 和 c 拥有同样的堆内存地址。
所以在执行判断 b==c 时,比较的是内存地址,所以其结果为 true,其余都为false。

进阶:如果将 1、2、4的==改为equals,结果又为什么呢?
点击进入 Object 的源码,查看 equals 对象执行的方法不就知道了。

Object 底层在进行比较的时候使用的就是 == ,所以答案不会发生改变。

又有人该说了,a 对象与 b 对象不是一模一样吗,为啥 equals 不相等,Long、String等系统对象都相等。
这就设置方法的重写。

    @Override
    public boolean equals(Object obj) {
    	if(this == obj) {
    		return true;
    	}
    	if(obj instanceof Four) {
    		Four f = (Four)obj;
    		return f.width==this.width;
    	}
    	return false;
    }

只要把对象的 equals 重写一下,此时 1、2、4 执行的结果就都为 true 了 。

发布了39 篇原创文章 · 获赞 20 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/cong____cong/article/details/104286025