==与.equals()的真正异同
排除误区
“==与.equals()的区别是,==是用来判断是否内存地址相同,而.equals()是用来判断内存地址指向的值是否相等。”
这句话为何❌呢?这是因为要分情况而论,某些情况下==与.equals()并无区别,而另一些情况下,才会有上述论断。
内存空间
(1)首先需要了解基本数据类型所处的内存空间:对于基本数据类型(byte,short,char,int,float,double,long,boolean)来说,他们是作为常量在方法区中的常量池里面以HashSet策略存储起来的,对于这样的字符串 "123" 也是相同的道理,在常量池中,一个常量只会对应一个地址,因此不管是再多的 "123","123" 这样的数据都只会存储一个地址,所以所有他们的引用都是指向的同一块地址,因此基本数据类型和String常量是可以直接通过==来直接比较的。
(2)另外,对于基本数据的包装类型(Byte, Short, Character,Integer,Float, Double,Long, Boolean)除了Float和Double之外,其他的六种都是实现了常量池的,因此对于这些数据类型而言,一般我们也可以直接通过==来判断是否相等。
(3)超出常量池范围,会导致相同值的内存地址不一致(堆内存)。例如:Integer 在常量池中的存储范围为[-128,127],127在这范围内,因此是直接存储于常量池的,而128不在这范围内,所以会在堆内存中创建一个新的对象来保存这个值,所以定义两个int = 128,他们分别指向了两个不同的对象地址,故而使用==进行比对会导致false。
== 与 .equals()的真正异同
(1)相同:在Object类型的equals方法是直接通过==来比较的,和==是没有任何区别的。这是因为在这里.equals()方法中就是做的==操作。也就是说,使用的对象类中如果没有重写.equals方法那么==与.equals的效果相同。
(2)不同:我们所有的类都直接或间接地继承自java.lang.Object类,因此我们可以通过重写equals方法来实现我们自己想要的比较方法。而常见的String这个类重写了equals 方法,比较的是String类中的char[]每个元素是否相等。因此才造成了开头的误区。