![6c555bad5fe2f3ba4b2df8c5fadcb505.png](https://img-blog.csdnimg.cn/img_convert/6c555bad5fe2f3ba4b2df8c5fadcb505.png)
用哪个???
我们先不要着急选择;
先来看看使用它们分别输出的结果;
根据结果才好剖析它们;
先来看“==”号
如下图示:
![73bb257e2872ddc204d299792b6dc652.png](https://img-blog.csdnimg.cn/img_convert/73bb257e2872ddc204d299792b6dc652.png)
上图示例分解:
![9dfb3781913860426bdbe16545f9445e.png](https://img-blog.csdnimg.cn/img_convert/9dfb3781913860426bdbe16545f9445e.png)
![4c10e802321fd1cd80d925d06688a311.png](https://img-blog.csdnimg.cn/img_convert/4c10e802321fd1cd80d925d06688a311.png)
再看 “equals”方法
我们再来使用equals看看结果,
会发现结果会有些许不同,
如下图示:
![d7bb7d10b684c2ed69e221507f59298a.png](https://img-blog.csdnimg.cn/img_convert/d7bb7d10b684c2ed69e221507f59298a.png)
上图示例分解:
![c0c51a7c008852d1bf9a4d409ec0e307.png](https://img-blog.csdnimg.cn/img_convert/c0c51a7c008852d1bf9a4d409ec0e307.png)
![944449eb108fd857689c855844608a5b.png](https://img-blog.csdnimg.cn/img_convert/944449eb108fd857689c855844608a5b.png)
为了更好的便于我们理解,
我们进入源代码来逐一看一下;
源码浅析
首先我们先打开Object对象的equals;
如下图示:
![8fefc72e43e18b5c92b637a7782ce8a6.png](https://img-blog.csdnimg.cn/img_convert/8fefc72e43e18b5c92b637a7782ce8a6.png)
根据万类之根Object对象的equals我们发现;
本质还是“==”来进行对比数值的;
只是Integer、String等进行方法重写而已。
我们再来看一下Integer包装类
(其他基本类型的包装类都类似在此就不一一举例了)
的 equals;
如下图示:
![c441563231497d378a93de385b2dcb3e.png](https://img-blog.csdnimg.cn/img_convert/c441563231497d378a93de385b2dcb3e.png)
只是将包装类转换成int然后进行值对比;
而本质依然是使用的“==”
可能你会有疑问了;
既然本质都是用的“==”为什么String对象前、后两次输出的值不同呢?
【“==”的输出的是false,“equals”输出的是true】
再回答问题之前我们先看看它的源代码;
String引用类型的equals的;
如下图示:
![4d57c107062a725f1b45899a64a25cf5.png](https://img-blog.csdnimg.cn/img_convert/4d57c107062a725f1b45899a64a25cf5.png)
我们看到判定对象如果是String实例的话,
就会将引用类型String转换成了基本类型char(想了解更多看这里)
进行循环比对,如果有不相同的值就返回false。
简言之,就是将引用比较转换成了值比较(想了解更多看这里)
我们事例使用equals对比的数值是”2”,
值是相同的,所以返回值是true。
从这个角度我们也能很好的理解为
1、 基本类型对比的是值
2、 引用类型对比的是内存地址
这就能解释明明我们的Person实例;
一个赋值的是“张三”,一个赋值的“李四”;
结果为什么是相等的呢?
看了Object对象的equals源码我们才知道,
因为他们对比的不是值,而是内存地址,
为了验证,
我们来看下图:
![fd4fa3fe10b3e4009109533a3aa56362.png](https://img-blog.csdnimg.cn/img_convert/fd4fa3fe10b3e4009109533a3aa56362.png)
上图示例分解:
![f7f031b30979b90c7a8576b6196f419c.png](https://img-blog.csdnimg.cn/img_convert/f7f031b30979b90c7a8576b6196f419c.png)
![62650b9be8656a3717674772dc5e836a.png](https://img-blog.csdnimg.cn/img_convert/62650b9be8656a3717674772dc5e836a.png)
我们可以看到输出的内存地址,
都是相同的;
那么返回true 也就无可厚非啦;
我们重新给开辟一个内存空间,并把原本赋值的“李四”改成与上个实例相对的“张三”后;
会发生什么情况呢?
如下图示:
![7896f2b1ca5447ddc4776cf99040eb71.png](https://img-blog.csdnimg.cn/img_convert/7896f2b1ca5447ddc4776cf99040eb71.png)
上图示例分解:
![ab3e4267b185c3c745dda197805d65e0.png](https://img-blog.csdnimg.cn/img_convert/ab3e4267b185c3c745dda197805d65e0.png)
![073ee476bfdcc87941b51f3fe6a1252b.png](https://img-blog.csdnimg.cn/img_convert/073ee476bfdcc87941b51f3fe6a1252b.png)
有没有同学已经提前猜度啦呢?
内容是相同啦,
但内存是不同的,
它既然比对的是内存地址,
返回的结果当然也就由原来的true,变成false啦。
重写toString() 方法
有聪明的同学或许会想到了;
我们上文不是刚说了吗?
引用类型String的equals方法;
能将引用比较转换成了值比较
我们将Person对象转换成String类型不就可以了吗?
那我们来试试,
如下图示:
![b9e1e058bca0c732477cda38f84df0e8.png](https://img-blog.csdnimg.cn/img_convert/b9e1e058bca0c732477cda38f84df0e8.png)
上图示例分解:
![89a4aefe2831fa2e17ca4a8fe76cecf0.png](https://img-blog.csdnimg.cn/img_convert/89a4aefe2831fa2e17ca4a8fe76cecf0.png)
![20f0267bb8fc45b2691f5b6689cc72a1.png](https://img-blog.csdnimg.cn/img_convert/20f0267bb8fc45b2691f5b6689cc72a1.png)
哎…
什么情况呢?
咋不行呢?
让我们进入到对象的toString()方法里来看下
![5ac96d974d1ea3bdc67023331d06f51c.png](https://img-blog.csdnimg.cn/img_convert/5ac96d974d1ea3bdc67023331d06f51c.png)
什么意思呢?
调用此方法给我返回的是;
对象的类名称 并 拼接一个16进制的hashcode码;
我们给他打印一下看看:
![54ad78c1449223e5fb4206ca1a21227d.png](https://img-blog.csdnimg.cn/img_convert/54ad78c1449223e5fb4206ca1a21227d.png)
上图示例分解:
![903dc64a11706f1cc584cbee2c613b88.png](https://img-blog.csdnimg.cn/img_convert/903dc64a11706f1cc584cbee2c613b88.png)
![7789dfa517a05d6fcd87d52e61c6e62f.png](https://img-blog.csdnimg.cn/img_convert/7789dfa517a05d6fcd87d52e61c6e62f.png)
确实不相同;
不怪人家给返回false。
那你可能要说了,
你可能气愤啦;
这个不对啊;
跟咱们上面说的不是相悖了吗?
别着急…
这个toString()不行;
那咱们给就他造一个行的呗;
怎么造呢;
如下图示:
![b741faa15adfe36bf2cdfdd5a05dd095.png](https://img-blog.csdnimg.cn/img_convert/b741faa15adfe36bf2cdfdd5a05dd095.png)
上图示例分解:
![13498dcce04ac5ec5ec3d1daf81e802c.png](https://img-blog.csdnimg.cn/img_convert/13498dcce04ac5ec5ec3d1daf81e802c.png)
我们在Person的实体对象内,
使用Override注解重写toString() 方法,
接着我们再次运行,看下效果
如下图示:
![447def610e3470c81e69f7c904609884.png](https://img-blog.csdnimg.cn/img_convert/447def610e3470c81e69f7c904609884.png)
上图示例分解:
![2a5bdf6b0548f201ff63efc36293ace2.png](https://img-blog.csdnimg.cn/img_convert/2a5bdf6b0548f201ff63efc36293ace2.png)
![10bf59c973f41a6d4fe6257da0b4efe1.png](https://img-blog.csdnimg.cn/img_convert/10bf59c973f41a6d4fe6257da0b4efe1.png)
我们发现重写后的结果,
符合我们的预期。
总结一下
到现在是不是你不是已经掌握了再使用的时候如何选择呢?
1、基本变量的比较方式我就用“==”
2、如果要比较实际内存中的内容,我们就要用“equals”方法
3、如果是我们自己定义的实例类,
我们自定义的类都是继承自object
从上文的源码分析推导出,
用“equals”或“==”都是一样的