-
“==” 解读
如果它的两边的对象都是引用类型,则比较的是引用地址是否相同
如果它的两边的对象都是基本类型,则比较值是否相等(Integer类型值不在-128~127范围内就也变成引用地址的对比了) -
“equals”解读
如果它的两边的对象都是引用类型,则比较的是引用地址是否相同
如果它的两边的对象都是基本类型,则比较值是否相等(Integer类型值哪怕不在-128~127范围内,也是值对比)
口头表述:
==和equals针对引用类型的情况下是一样的,都是比较的引用地址是否相同;但是equals作为方法可以被重写,重写后就会根据我们自己的想法去比较了,比如比较学生对象的名字和年龄是否相等。
而针对基本类型,String类型永远都是比较值;而Integer不同,==只在正负128以内才比较值,超过了就比较引用地址了,但equals永远比较值。
因为String和Integer都默认重写过equals方法
坑:在实体类上加了 @Data ,会默认给你这个对象重写equals,那么它会去判断对象里面的各个值是否相等。不太懂的人就会以为哪里理解错了,删掉@Data再试吧
知识点延伸
为什么equals情况下Integer达到正负128也是值对比?
对象是比较引用地址的, 但是Integer对象重写了equals方法,把它改成比较值了。
为什么Integer的==到正负128就变成引用地址对比了?
因为-128~127是存在缓存的,jvm初始化的时候,就会在常量池中存好这些值,那么如下图,两个变量 a和b,都是127,那么指向的地址就都是常量池中的地址B,所以他俩相等。
但是变量c=128,他就无法指向常量池了,因为常量池里没128,所以他指向了堆中的地址q,这是新new出来的对象。
-128~127范围内的Integer类型和String一样,如果值相同,就会指向常量池中同一个地址。
上一个问题中两个变量指向了常量池中同一个地址,修改其中一个变量会为什么不会导致另外一个变量的值被改变?
修改值后,会修改栈中的地址指向,直接指向新的常量池地址,至于老地址中值则不动,所以另外一个变量的值也不动。
String也一样,两个值相同的String参数指向同一个地址,但是其中一个变量 s = s+“啊”;后就会重新在常量池中生成新的一个字符串和地址,然后修改栈中的地址指向。
这也是为什么不要频繁对String类型的变量进行拼接修改操作的原因了,因为一直在常量池中生成新的字符串,会占用内存空间。