基本数据类型和包装类型的 == 与 equals 的根本性区别(坑人小彩蛋)

自从在学校刷程序结果题以来,脑海一直有个印象, == 就是比较地址,equals 才是比较值。今天跟个技术大佬聊,才知道大家其实都很容易被刷题误导了。这篇文章,将彻底解决这两者的纠缠不清!

(1)equals的底层其实还是 == :

多说无益,直接上源码:
基本数据类型和包装类型的 == 与 equals 的根本性区别(坑人小彩蛋)

这也就是说,对象等引用类型如果用equals,比较的其实也是地址,跟使用 == 没有半毛钱区别:

基本数据类型和包装类型的 == 与 equals 的根本性区别(坑人小彩蛋)

(2)基本数据类型比较的是‘值’,这点无可挑剔,基本数据类型的包装类型 == 和 equals ,比较的都是 ‘值’ ,不关地址的任何事情!

基本数据类型和包装类型的 == 与 equals 的根本性区别(坑人小彩蛋)

这又是为什么呢?!不是说 ‘==’ 比较的是地址, 对象equals也是比较地址吗??这是包装类型里面重写了equals方法!

基本数据类型和包装类型的 == 与 equals 的根本性区别(坑人小彩蛋)

如果你觉得Integer是这样,以后都放心 == ,那就出问题了:

基本数据类型和包装类型的 == 与 equals 的根本性区别(坑人小彩蛋)

这又是为什么呢?那是因为Integer有一个默认值范围,128以内,它们地址相等, ‘=’里面比较的也确实还是地址!只不过在一定范围值内,Integer自己做了缓存列表!!所以Integer分配的都是同一个地址,就这么简单!
详细原因请看: https://blog.****.net/whiteBearClimb/article/details/109236747
同理,Long也是这个熊样:

基本数据类型和包装类型的 == 与 equals 的根本性区别(坑人小彩蛋)

如果认为Double理所当然也是这样,那就大错特错了!继续看…

(3)对于Float和Double这些浮点数包装类!永远不要 == 去比较!

基本数据类型和包装类型的 == 与 equals 的根本性区别(坑人小彩蛋)

这里很清楚看到!跟Integer那种精确类型的不一样!Double包装类型如果用 == 比较!它是false!原因就是浮点型包装类数据没有默认的缓存列表,每次都是崭新地new创建一个,啪的一声!很快啊!如果确实要 = 比较,又倔强的不想用equals ,那就写:Double.doubleToLongBits(d) 吧。就是转成LongBits的Long类型再比较。

基本数据类型和包装类型的 == 与 equals 的根本性区别(坑人小彩蛋)

Float不讲武德,也学Double搞偷袭。

(4)说完基本数据类型!String不算基本数据类型吧!那它的 == 和 equals分别比较什么呢?

基本数据类型和包装类型的 == 与 equals 的根本性区别(坑人小彩蛋)

这个是老生常谈的老问题了,a和b因为都是指向运行时常量池中的 “ * ” ,所以地址 == 比较当然一样,equals 方法被重写,变成单纯比较值,那当然也一样。a1 和 b1 ,new出来的,脚趾头想都知道它们不是一家人。但是 a1 , b1它们的值一样。

基本数据类型和包装类型的 == 与 equals 的根本性区别(坑人小彩蛋)

总结:包装类型,引用类型,一定,一定,一定用equals!!!equals方法本来也是 == 比较地址的,由于很多Object的子类对它进行了重写,才实现了值的比较!不要张口就来说equals一定比较值!!