java 编译器如何知道继承的方法?

How does the java compiler know of inherited methods?

我们在Java中使用继承来抽象出超类中的类似行为,让所有子类继承它。这样做的一个好处是,我们现在只有一个方法副本要维护(即在超类中)。

Class Animal
{
   public void makeNoise()
   {

   }

   public void sleep()
   {

   }   
} 

Class Cat extends Animal
{
     // Override the makeNoise method
     public void makeNoise()
     {

     }
}

Class someClass
{
     public static void main(String args[])
     {
          Cat fluffy = new Cat();

          fluffy.sleep();
     }
}

我试图了解 Java 编译器如何知道 sleep() 方法用于 Cat 类型引用。 Cat 子类中不能有该方法的副本(这违背了将它放在超类中并让所有子类 继承它的目的)。此信息是否存储在其他地方?

当编译器看到 fluffy.sleep() 时,它首先在 Cat class 中查找名为 sleep 的 public 实例方法,它不带参数。因为它没有找到它,所以它将继承链向上移动到 Animal,并对 Animal 进行相同的检查。它在那里找到了它,所以一切都很好。

除了代码和 Java 字节代码之外,此信息实际上 "stored" 并不存在。

在接口的情况下,我们可以调用 Object class 方法,而无需接口扩展 Object。 例如:-

public interface Test { 
}

public class MyClass extends Object implements Test {

public static void main() {
Test test = new MyClass();
test.hashCode();
// You can call Object Class methods on Test interface and Test interface
//does not extends Object.

}

//在Java规范9.2中:- 如果一个接口没有直接超接口,那么该接口隐式声明一个public抽象成员方法m,签名为s,return类型为r,并抛出每个public实例方法m对应的子句t具有签名 s,return 类型 r,并在 Object 中声明的 throws 子句 t,除非是抽象方法 具有相同的签名,相同的 return 类型,并且兼容的 throws 子句是 由接口显式声明。 如果在 Object.

中 m 被声明为 final 的情况下,接口显式声明这样的方法 m 是一个编译时错误。