阅读 9

【java基础】==和equals

我是 啤酒就辣条,一个Java。
学而时习之,不亦说乎?希望通过博客的形式,总结、分享,梳理自己、帮助他人。
另外,啤酒就辣条,味道不错哦~

两种相等

==是比较两个对象引用所指向的地址是否相同。

equals本身等同于==,但是由于经常被重写,所以常被用来判断两个对象内容是否相同。

示例展示

首先新建一个类CPU

public class CPU {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
复制代码
public class EqualsTest {
    public static void main(String[] args) {
        CPU cpu1 = new CPU();cpu1.setName("因特尔");
        CPU cpu2 = new CPU();cpu1.setName("因特尔");
        CPU cpu3 = cpu1;
        System.out.println(cpu1 == cpu2);//false
        System.out.println(cpu1.equals(cpu2));//fasle
        System.out.println(cpu1 == cpu3);//true
        System.out.println(cpu1.equals(cpu3));//true
    }
}
复制代码

直接看,==equals等价,这是为什么呢?要看一下万物之祖Object

public class Object {
    public boolean equals(Object obj) {
        return (this == obj); //所以说,`equals`本身等同于`==`
    }
}
复制代码

常常被重写的equals

我们常常需要比较两个对象内容是否相同,而不是他们的地址。所以,JDK中多数类都重写了equals方法。

    // String 的 equals方法比较的是字符串内容本身
    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
    // Integer 的 equals方法比较的是数值内容本身
    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
复制代码
public class EqualsTest {
    public static void main(String[] args) {
        Integer integer1 = new Integer(500);
        Integer integer2 = new Integer(500);
        System.out.println(integer1 == integer2); //fasle
        System.out.println(integer1.equals(integer2)); //true
    }
}
复制代码

从上面的例子可以看出equals此时比较的是数值内容。

关于Integer的小秘密

我们将上面的例子稍微改造一下:

public class EqualsTest {
    public static void main(String[] args) {
        Integer integer1 = 500;
        Integer integer2 = 500;
        System.out.println(integer1 == integer2);//false
        System.out.println(integer1.equals(integer2));//true
    }
}
复制代码

和上面的例子相比,此时integer1和integer2需要装箱操作,但是不影响结果。

but,我们将数值调小一点:

public class EqualsTest {
    public static void main(String[] args) {
        Integer integer1 = 50;
        Integer integer2 = 50
        System.out.println(integer1 == integer2);//true
        System.out.println(integer1.equals(integer2));//true
    }
}
复制代码

此时发现integer1 == integer2居然相等,说明指向同一块内存。这一现象的原因是:Integer的[-128,127]这个范围的数值缓存在常量池,所以无论多少引用,只要数值在这个范围内,引用都指向同一地址

所以对于Integer比较数值大小,无论数值是否需要经历装箱,都是用equals比较大小