为什么这段代码中有Unhandled Exception?
Why there is Unhandled Exception in this code?
我遇到了以下代码:
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支持这个的原因是什么?这不应该作为错误提交吗?
因为您正在使用 Animal
引用来引用 Dog
。 Animal.eat
的签名包括 Exception
。编译器知道 Dog
是一种 Animal
,但是一旦您使用 Animal
引用,它直到运行时才知道它是 Dog
。
换句话说,所有 Dog
(s) 都是 Animal
(s) 但并非所有 Animal
(s) 都是 Dog
(s)。
编辑
你本可以添加演员
((Dog) a).eat(); //would compile
在运行时,如果 a
实际上不是 Dog
,那将失败。
Animal a = new Dog();
在OOP (Object Oriented Programming)
中,这个叫做polymorphism
。而在 Java 中(主要是在 OOP 支持语言中,例如 C#),这种行为是编译检查。这意味着编译器在 编译时 只知道 a 是动物,直到 运行时才能知道 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();
希望对您有所帮助:)
首先你没有遵守方法覆盖的规则。如果 Base class 方法抛出任何异常,则子 class 方法必须抛出相等或低级异常。现在这段代码可以正常工作,因为它遵循方法覆盖规则。另外@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();
}
}
我遇到了以下代码:
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支持这个的原因是什么?这不应该作为错误提交吗?
因为您正在使用 Animal
引用来引用 Dog
。 Animal.eat
的签名包括 Exception
。编译器知道 Dog
是一种 Animal
,但是一旦您使用 Animal
引用,它直到运行时才知道它是 Dog
。
换句话说,所有 Dog
(s) 都是 Animal
(s) 但并非所有 Animal
(s) 都是 Dog
(s)。
编辑
你本可以添加演员
((Dog) a).eat(); //would compile
在运行时,如果 a
实际上不是 Dog
,那将失败。
Animal a = new Dog();
在OOP (Object Oriented Programming)
中,这个叫做polymorphism
。而在 Java 中(主要是在 OOP 支持语言中,例如 C#),这种行为是编译检查。这意味着编译器在 编译时 只知道 a 是动物,直到 运行时才能知道 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();
希望对您有所帮助:)
首先你没有遵守方法覆盖的规则。如果 Base class 方法抛出任何异常,则子 class 方法必须抛出相等或低级异常。现在这段代码可以正常工作,因为它遵循方法覆盖规则。另外@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();
}
}