Java 方法在子类重写的父类中引发异常
如果实例方法被子类重写,为什么引用到父类的子类实例需要捕获异常。 这是一张清晰的图片Java 方法在子类重写的父类中引发异常,java,Java,如果实例方法被子类重写,为什么引用到父类的子类实例需要捕获异常。 这是一张清晰的图片 public class Animal{ public void printName() throws Exception{ System.out.println("Animal Method"); } } public class Dog extends Animal{ public void printName(){ System.out.println("Dog Meth
public class Animal{
public void printName() throws Exception{
System.out.println("Animal Method");
}
}
public class Dog extends Animal{
public void printName(){
System.out.println("Dog Method");
}
public static void main(String[] args){
Animal m = new Dog();
((Dog)m).printName(); //prints Dog Method
m.printName(); // this is supposed to be overridden and will print "Dog Method", why the throws Exception of Animal method printName was copied. to the instance
}
}
变量
m
的引用类型是Animal,因此在编译时,使用类Animal的方法签名,尽管在运行代码时,实际调用的方法是子类中的方法。变量m
的引用类型是Animal,因此在编译时,使用类Animal的方法签名,但在运行代码时,实际调用的方法是子类中的方法。这是因为变量m被定义为Animal,编译器看到Animal的printName方法抛出异常
您可能知道可以调用变量的方法是由其类型、编译时类型声明定义的,如:
Animal m;
即使m实际上指向一只狗,你也只能在m上调用Animal的方法。(除非你投)
同样,它可能抛出的异常也由其声明的类型定义。这就是为什么在对Dog声明的对象调用该方法时,不需要捕获异常
真正有趣的是,派生类中的重写方法只能从throws子句中删除异常,或者使它们更具体,但不能添加任何异常,因为这会导致对基类调用方法的人产生令人惊讶的结果。这是因为变量m被定义为动物,编译器看到动物的printName方法抛出异常 您可能知道可以调用变量的方法是由其类型、编译时类型声明定义的,如:
Animal m;
即使m实际上指向一只狗,你也只能在m上调用Animal的方法。(除非你投)
同样,它可能抛出的异常也由其声明的类型定义。这就是为什么在对Dog声明的对象调用该方法时,不需要捕获异常
真正有趣的是,派生类中的重写方法只能从throws子句中删除异常,或者使它们更具体,但不能添加任何异常,因为这将导致对基类调用方法的人产生令人惊讶的结果。在编译时,
m
实际上是Animal
类型,所以您应该捕获异常,因为异常被检查,并且编译时没有dog对象,但在运行时,m是dog
类型。因此将调用dogprintName
方法,但在这一行中,((dog)m).printName()
将其强制转换为dog
,因此不需要捕获异常。在编译时,m
实际上是动物类型,因此,您应该捕获异常,因为检查了异常,并且编译时没有dog对象,但在运行时,m是dog
类型。因此将调用dogprintName
方法,但在这一行中,((dog)m).printName()
将其强制转换为dog
,因此无需捕获异常