为什么此代码中存在未处理的异常?

时间:2015-01-02 06:43:53

标签: java exception

我遇到了以下代码:

class Animal{
    public void eat() throws Exception {}
}

class Dog extends Animal{
    public void eat(){} //no exception thrown
    public static void main(String[] args){
          Animal a = new Dog();
          Dog d = new Dog();
          d.eat();   //ok
          a.eat();  //does not compile!..(1)
    }
}

这里,(1)即使在运行时也不会编译Dog的eat()方法。为什么会这样? Java支持这个的原因是什么?这不应该是一个错误吗?

3 个答案:

答案 0 :(得分:7)

因为您使用Animal引用来引用DogAnimal.eat的签名包含Exception。编译器知道Dog是一种Animal,但是一旦使用Animal引用,它就不知道它是Dog直到运行时。

换句话说,所有Dog(s)都是Animal(s),但并非所有Animal都是Dog(s)。

修改

您可以添加演员

((Dog) a).eat();  //would compile

在运行时,如果a实际上不是Dog,则会失败。

答案 1 :(得分:3)

Animal a = new Dog();
OOP (Object Oriented Programming)中的

,称为polymorphism。在Java中(主要是在OOP支持语言中,如C#),这种行为是编译检查。这意味着编译时的编译器只知道a是动物,并且在运行时之前不能知道它是狗。

例如:

Animal a = new Dog();
a.bark(); // cannot. because compiler doesn't know a is a dog until runtime
((Dog)a).bark(); // yes. we say to compiler: a **must** be a dog

另一个例子是:

    Animal a = new Cat();
    // yes. can compile. we force compiler to know this animal is a dog. 
    //but will run-time exception because in fact this is a cat
    ((Dog)a).bark(); 

希望这有帮助:)

答案 2 :(得分:3)

首先,您没有遵循方法覆盖的规则。如果Base类方法抛出任何Exception,那么子类方法必须抛出相等或低级异常。现在这个代码将正常工作,因为它遵循覆盖规则的方法。另外@Elliot说正确的事情,编译器在编译时不知道dog对象(正如Animal所指的那样)。它只会在运行时解决。

class Animal{
public void eat() throws Exception {}
}

class Test extends Animal{
  public void eat()throws Exception{} 
  public static void main(String[] args)throws Exception{
      Animal a = new Test();
      Test d = new Test();
      d.eat();
      a.eat();  
}
}