直接上代码
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 了 。