在学Java中,遇到一个重写object类的equals方法,代码如下
public class Phone {
public String name;
public int price;
public Phone(String name, int price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
//equaLs方法进行重写:
public boolean equals(Object obj) {
System.out.println(obj); //Phone@1b6d3586
if (obj instanceof Phone) {//是否属于Phone类的对象
Phone other = (Phone) obj;//将obj转为Phone类型:
if (this.getName().equals(other.getName()) && this.getPrice() == other.getPrice()) {
return true;
}
}
return false;
}
}
我定义了一个Phone类,有name和price两个属性,重写equals方法,只要name和price都一样就认为一样。
然后我测试了一下:
public class Test {
public static void main(String[] args) {
Phone p1 = new Phone("P30",5000);
Phone p2 = new Phone("P30",5000);
System.out.println(p1.equals(p2)); //true
}
}
上面结果是true,达到效果,我不理解的是为什么需要Phone other = (Phone) obj;进行强转,在equals方法第一行我打印了obj结果是Phone@1b6d3586,那么是不是可以说明obj其实就是Phone的实列?如果是为什么需要强转?如果不是那么obj instanceof Phone结果是false也运行不进去啊?
是的没错,你传入的这个对象是Phone类型的一个实例,所以你不用怀疑为什么能进去if分支
接下来注意 你重写的是所有类的父类Object的equals方法,这个方法的形参是一个Object类型的对象,在JAVA里任何类型都是Object类型的子类,说白了这里只是告诉编译器什么类型都可以往里传,如果这里不是Object类型的形参,那你覆盖的就不是Object类的equals方法了而只是自己写了一个全新的equals方法,这当然也可以,而且比较的结果仍然是正确的,然而不重写Object类的equals方法的话,Java的标准库和其他第三方库通常依赖于equals方法的重写(Object类里的)来正确地比较对象,是会带来问题的。
好了现在问题变成为什么又要强转回去了,因为编译器现在只知道你传入的对象是一个Object类型的对象,我就偏偏不强转了怎么滴,可是Object类有getName()方法吗?有getPrice()方法吗?所以编译器就不乐意了,你只告诉我你是Object类型的你又没有这些方法,肯定就给你报错了。(不信你可以写一下试试,就不强转看看代码报不报红)
所以我们强转,告诉编译器其实刚才我只是装的,我只是为了满足你让我重写这个方法的门槛而已,现在我能重写这个方法了我就不演了,其实我是Phone哥,我有getName()方法和getPrice()方法,接下来就是就掏出自己的方法一顿操作了。
注意楼上有提及到你重写了equals方法就一定要重写hashCode方法,如果你不重写hashCode方法的话在把自定义对象丢进集合类的时候有意外的惊喜哦,至于为什么就不是这篇问题的范畴了,自行百度理解即可。