澄清 - 据我了解,以下方法都是Object.equals
的覆盖。他们是超载而我没有正确理解这一点?
我正在运行此代码:
public class AA
{
private int _val=0;
public AA()
{
_val=5;
}
}
public class BB extends AA
{
public BB()
{
....
}
public boolean equals(BB ob)
{
return false;
}
public boolean equals(Object ob)
{
return true;
}
public boolean equals(AA ob)
{
return true;
}
public static void main(String args[])
{
AA a2=new BB();
BB b1=new BB();
if((a2.equals(b1)))
System.out.println("hi");
}
}
AA类没有equals
方法
我试图找出第二种方法被触发而不是第一种方法。我的理解是:
equals
方法,我认为是
编译时编译器想要从equals
运行Object
类。equals
方法
Object
。但是,我不清楚的是,如果定义了发送的对象并且实际上是BB对象,则选择第二个方法(Object ob)
而不是第一个(BB ob)
。
非常感谢您的反馈!
答案 0 :(得分:4)
当您调用a.equals(b)
时,编译器会查看AA中的equals
方法。如果它在那里找到合适的,它会使用它。在这种情况下,AA没有称为'等于'的方法。所以它加强了继承链,并再次看起来。这一次,它正在查看Object,它找到了Object.equals(Object)
。在运行时,它会找到覆盖率最高的版本并调用它。
因此,如果它仍然只是寻找一个名为'equals'的方法,为什么它不能在运行时找到更具体的版本equals(BB)
?
BB.equals(BB)
不被视为Object.equals(Object)
的覆盖。它有一个更具体的参数,并且不能处理普通的Object。想象一下这些类型是名称的一部分:
编译器选择了equals_Object
方法,因此在运行时JVM将找不到equals_BB
方法,因为它没有查找它。
答案 1 :(得分:2)
在运行时选择 ,在编译时只需知道对象是AA
时,就会在编译时选择它们。根据对象的实际运行时类型,在运行时仅选择覆盖,但仍会使用在编译时选择的重载。