关于==和equals()方法

  • 对于8大基本类型

    • 无法使用equals()方法,只能使用==,比较的是两个对象的值
  • 对于引用类型

    • ==,比较的是两个对象的地址
    • 默认的equals()方法是等价==的,之所以会有差异,是因为equals方法可以进行重写
public class Test {
    public static void main(String[] args) {
        String a = "hello";
        String b = "hello";
        String c = new String("hello");

        //在java中字符串的值是不可改变的,相同的字符串在堆内存中只会存一份,所以a和b指向的是同一个对象;
        System.out.println(a==b);//true

        //a和c在堆内存中的地址不同(c是新开辟的),所以a和b指向的不是同一个对象;
        System.out.println(a==c);//false

        //这里的equals等价于==,因为a和b地址相同
        System.out.println(a.equals(b));//true

        //这里equals比较后两个不同的对象,但结果确实true
            //说明Strung重写过了equals方法
        System.out.println(a.equals(c));//true

        //ab为同一个对象,应该拥有相同的hashcode,但c为另一个对象,hashchode应该不同
            //说明String重写了hashcode
        System.out.println(a.hashCode());
        System.out.println(b.hashCode());
        System.out.println(c.hashCode());

    }
}

内存分析

image-20201208114219690

查看String中的源码

可以看出在String类中对euqals()方法和hashcode方法进行了重写

  • equals
image-20201208112930101
  • equals
image-20201208112837987

8大基本类型的包装类

  • 这些引用类型的包装类也都重写了equals()和hashcode
public class Test {
    public static void main(String[] args) {

        double j = 20.0;
        Double k = 20.0;
        Double m = 20.0;
        Double n = new Double(20.0);

        //基本类型——比较值
            //Integer类型自动拆箱
        System.out.println(j==k);//true
        System.out.println(j==m);//true
        System.out.println(j==n);//true

        //引用类型——比较地址
            //但结果都是true,因为Double重写了equals()方法
        System.out.println(k.equals(j));//true,自动装箱、拆箱
        System.out.println(k.equals(m));//true
        System.out.println(k.equals(n));//true
            //n是另开辟的对象,但也是相同的hashcode,被视作同一个对象,因为Double也重写了hashcode方法
        System.out.println(k.hashCode());//1077149696
        System.out.println(m.hashCode());//1077149696
        System.out.println(n.hashCode());//1077149696
        
    }
}

由此得出结论

  • hashcode
    • 因为重写的存在,hashcode相同可能不是同一个对象
    • hashcode不同的一定不是同一个对象的
  • equals
    • 因为重写的存在,两个对象euqals相等,不一定是同一个对象,如果hashcode没有重写,hashcode也不一定相等,因为从Object继承来的hashCode是基于对象的ID实现的。

相同的对象,应该拥有相同的地址和hashcode,因此在判断两个对象是否相同时需要同时重写hashcode,和equals方法

参考资料hashcode详解 - 有梦想的老王 - 博客园 (cnblogs.com)

posted @ 2020-12-08 11:59  球球z  阅读(85)  评论(0)    收藏  举报