每天都在用"=="和"equals"却不知道原理,先回顾一下什么是基础类型和引用类型。
基础数据类型:byte、short、int、long、char、float、double、boolean
基础数据的(包装类)引用类型:Byte、Short、Integer、Long、Character、Float、Double、Boolean
任何引用类型的默认值为null,null既不是对象也不是一种类型,它是一种特殊的值
“==”
1、当“==”两边的对象属于基础类型时,比较的是对象的值是否相等
2、当“==”两边的对象属于引用类型时,比较的是对象的引用是否相等,也就是堆中的地址是否相等
下图为什么是false,原因是一个在常量池中,一个在堆中new了一个对象
可以查看class字节码,这是创建了一个新的对象,并不是引用同个常量池,分成了#2和#3
为什么下图比较对象的值相等,却返回false,原因Integer取值范围-128~127,超出范围按对象的地址来比较,所以引用型间的比较用"equals",而不是用"=="
3、如果"=="一边是基础类型和另一边是引用类型,会拆箱转成基本类型去比较,一般我们写代码也不会这样写
总结:“==”对于基本类型,比较的是值是否相等;对于引用类型,比较的是地址是否相等
个人副业,专注各种平台的优惠券(外卖、电影、电商、生活),【猴哥探店】小程序
"equals"
equals是对两个对象的地址进行比较,可以理解为比较两个引用是否相同,有些引用类型重写了equals方法,例如:Integer,Double,String...可以查看源码,都重写了equals方法
结果全是true,为什么全部都为true,上面的例子说了,引用类型如果是new 的话会在堆中重新创建一个新对象,而不是共用一个常量池地址。区别就在于String 重写Object的equals方法,其他包装类也一样,可以查看源码
总结:
1、如果类没有重写equals, 比较的是对象的地址是否相等
2、如果重写了equals,比较的是两个对象的属性值是否相等(两个对象是否相等)
Objects.equals(s1,s2)
任何引用类型的默认值为null,null既不是对象也不是一种类型,它是一种特殊的值,当我们用equals去比较时没对空值做判断,会抛出NullPointException,所以有时候我们可以用Objects.equals去比较两个对象,Objects.equals()不会抛出空指针异常
源码
个人副业,专注各种平台的优惠券(外卖、电影、电商、生活),【猴哥探店】小程序