Java基础知识:==和equals的区别

无论是在面试或者在工作中,==和equals是我们始终无法避免的两个基本使用,但是,==和equals又是不同的,一旦用错了,那么程序就会出现错误,但是排查的时候又很难发现。

我们都知道,Java中有8种基本的数据类型,分别是:Byte,short,int,long,double,folat,boolean,char,其中占一个字节的是byte,short和char占两个字节,int,float占四个字节,double和long占8个字节,boolean只有true和false,这八种数据变量中直接存储数据的值。另外,这8种基本数据类型对应着各自的封装类型,提供了更多的方法,且不进行初始化时值默认为空(基本数据类型必须初始化)。

除此之外,java中还存在着引用数据类型,我们常使用的String就是一种引用类型。

==比较时的作用

简单点说:基础数据类型:==比较的是他们的值是否相等,比如两个int类型的变量,比较的是变量的值是否一样。而引用数据类型:==比较的是引用的地址是否相同,比如说新建了两个对象,比较的是两个对象的地址是否一样。

比如,我们拿int类型和Integer类型来做测试:、

        int a = 1;
        int b = 2;
        int c = 1;
        System.out.println("================基本类型=============");
        System.out.println(a == c);
        System.out.println(a == b);
        System.out.println(b == c);
        Integer integera = new Integer(1);
        Integer integerb = new Integer(1);
        Integer integerc = integera;
        Integer integerd = new Integer(1);
        System.out.println("================引用类型=============");
        System.out.println(integera == integerb);
        System.out.println(integerb == integerc);
        System.out.println(integera == integerc);
        System.out.println(integera == integerd);

可以看到输出结果如下:

从这里我们可以看出来,当使用==时,如果是基本类型,直接比较的就是数据的值,因为基本类型保存的就是数据的值,而引用类型保存的是内存中的地址,所以==在比较引用类型时比较的是内存中的地址,可以看到,integera和integerc内存地址相同,此时结果为true,但是,当integera与integerd比较时,虽然两者的值相同,但是引用类型每次new的时候会开辟一片新的区域,所以两者地址是不同的,此时结果为false。

注:我们都知道,引用类型保存的是内存的地址,比如String是不可变的,如果你定义了一个String a = "a";然后令 a = "b",此时改变了String 的内容吗?答案是:没有。因为此时仅仅是在内存中重新开辟了一个区间,修改了a的内存地址,但是原来的“a”依然在内存中存在。那么这个时候又出现一个问题,如果我定义了好几个String类型,他们的值是相同的,这个时候使用==和equals有区别吗?代码如下:

        String a = "a";
        String b = "a";
        String c = new String("a");
        System.out.println(a.equals(b));
        System.out.println(a == b);
        System.out.println(a.equals(c));
        System.out.println(a == c);

结果如下:

问题来了,既然String是不可变的,那么a和b应该指向的是不同的地址,为什么使用==和equals都是true呢?原因就是:Java对于字符串序列相同的两个String变量指向的都是同一个地址,也就是说,只要值相同,不管有多少个变量,都指向同一个地址,所以此时无论使用equals和==都是true。那么使用new String 为啥不同呢?因为一旦使用new,那么就相当于重新开辟了内存空间,此时,虽然值相同,但是内存地址不同,所以结果不同

equals比较

当使用equals比较时,equals只能用于封装数据类型,但是并不是说equals只能用于引用数据的比较,equals方法只能由类或者对象去调用,而封装数据类型就是一个类。equals方法如果使用jdk自带的equals方法,那么就只能比较封装数据类型和字符串,如果想要比较对象和其他的object类型,需要重写该方法。

equals比较的两者的内容是否相等,不会比较内存地址。通过查看object类中的equals源码,我们可以发现,其实equals内部使用的依然是==,这里可能很多人会说,两个一样,但是为什么==如果基本类型比较的就是值是否相等,引用类型就比较的是内存地址,而equals单纯的比较的是两者的内容呢?

原因就是,Java重写了object的equals方法,如下,Integer包装类重写的equals方法:

String引用类型中对equals的重写:

通过这里我们就可以看出来,此时比较的只是值了,并不涉及内存地址。所以测试如下:

        Integer integera = new Integer(1);
        Integer integerb = new Integer(1);
        Integer integerc = integera;
        Integer integerd = new Integer(1);
        System.out.println(integera.equals(integerb));
        System.out.println(integera.equals(a));
        System.out.println(integerb.equals(integerc));

结果如下:

通过这里我们看出来,即便是不同的内存地址,只要内存地址的内容一样,equals就会返回true,但是,此时使用==会返回false。

如果你想比较两个对象是否相同,那么只能重写equals方法了,否则,无论使用哪一种,返回的都是false,因为他们都是用的==,比较的是地址

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值