关于==和equals()方法
-
对于8大基本类型
- 无法使用
equals()方法,只能使用==,比较的是两个对象的值
- 无法使用
-
对于引用类型
==,比较的是两个对象的地址- 默认的
equals()方法是等价于==的,之所以会有差异,是因为equals方法可以进行重写
public class Test {
public static void main(String[] args) {
String a = "hello";
String b = "hello";
String c = new String("hello");
//在java中字符串的值是不可改变的,相同的字符串在堆内存中只会存一份,所以a和b指向的是同一个对象;
System.out.println(a==b);//true
//a和c在堆内存中的地址不同(c是新开辟的),所以a和b指向的不是同一个对象;
System.out.println(a==c);//false
//这里的equals等价于==,因为a和b地址相同
System.out.println(a.equals(b));//true
//这里equals比较后两个不同的对象,但结果确实true
//说明Strung重写过了equals方法
System.out.println(a.equals(c));//true
//ab为同一个对象,应该拥有相同的hashcode,但c为另一个对象,hashchode应该不同
//说明String重写了hashcode
System.out.println(a.hashCode());
System.out.println(b.hashCode());
System.out.println(c.hashCode());
}
}
内存分析
查看String中的源码
可以看出在String类中对euqals()方法和hashcode方法进行了重写
- equals
- equals
8大基本类型的包装类
- 这些引用类型的包装类也都重写了equals()和hashcode
public class Test {
public static void main(String[] args) {
double j = 20.0;
Double k = 20.0;
Double m = 20.0;
Double n = new Double(20.0);
//基本类型——比较值
//Integer类型自动拆箱
System.out.println(j==k);//true
System.out.println(j==m);//true
System.out.println(j==n);//true
//引用类型——比较地址
//但结果都是true,因为Double重写了equals()方法
System.out.println(k.equals(j));//true,自动装箱、拆箱
System.out.println(k.equals(m));//true
System.out.println(k.equals(n));//true
//n是另开辟的对象,但也是相同的hashcode,被视作同一个对象,因为Double也重写了hashcode方法
System.out.println(k.hashCode());//1077149696
System.out.println(m.hashCode());//1077149696
System.out.println(n.hashCode());//1077149696
}
}
由此得出结论
- hashcode
- 因为重写的存在,hashcode相同可能不是同一个对象
- 但hashcode不同的一定不是同一个对象的
- equals
- 因为重写的存在,两个对象euqals相等,不一定是同一个对象,如果hashcode没有重写,hashcode也不一定相等,因为从Object继承来的hashCode是基于对象的ID实现的。
相同的对象,应该拥有相同的地址和hashcode,因此在判断两个对象是否相同时需要同时重写hashcode,和equals方法

浙公网安备 33010602011771号