我的Parent
课程是:
import java.io.IOException;
public class Parent {
int x = 0;
public int getX() throws IOException{
if(x<=0){
throw new IOException();
}
return x;
}
}
我extend
这个类写了一个子类Child
:
public class Child1 extends Parent{
public int getX(){
return x+10;
}
}
请注意,当{em>覆盖 Child
类中的 getX 方法时,我已从方法定义中删除了throws
子句。现在结果如下在预期的编译器的异常行为中:
new Parent().getX() ;
如果不按预期将包含在try-catch
块中,
就不会编译。
new Child().getX() ;
编译时不将其括在try-catch
块中。
但是下面的代码行需要try-catch块。
Parent p = new Child();
p.getX();
正如可以预见的那样,即在运行时多态性期间使用父类引用来调用子方法,为什么Java的设计者没有强制要求在覆盖特定父代时在方法定义中包含throws子句类方法?我的意思是如果父类方法在其定义中有throws子句,那么在覆盖它时,覆盖方法还应该包括throws子句,不是吗?
答案 0 :(得分:32)
不,这是合适的 - 重写的方法可以对它抛出(和返回)的内容有更多的限制,因为这对于在编译时知道的调用者他们将使用重写方法,并且不想打扰不会发生的异常等。它必须更具限制性而不是更多许可,因此它不会让那些的呼叫者感到惊讶通过父声明访问它。
通过Parent
类型的引用使用重写方法永远不会违反“它可能抛出IOException
”的合同 - 没有异常不会违反合同。反过来(如果父没有声明异常,但覆盖方法确实如此)将违反合同。
答案 1 :(得分:3)
好吧,重写方法可能根本不会抛出任何异常(或至少更少的异常),因此您可以从throw子句(或整个throw子句)中删除异常。
假设重写方法捕获所有异常,记录它们并返回特殊值。虽然这不是好的样式(它会改变方法的语义),但它仍然是可能的,因此如果你在编译时知道你正在处理{{1},你就不必捕获永远不会抛出的异常。 }。
添加例外不起作用,因为通过Child
引用访问它的类的用户不知道Parent
可能添加的任何例外。
答案 2 :(得分:2)
您可以自由地覆盖没有throws关键字的方法,因为如果您想通过控制所有异常来开发方法,那么您可以通过覆盖没有任何throws子句的方法来实现。
但请记住,如果要在子类方法中包含throws子句,那么throws子句必须与必须相同的异常或其超类方法抛出的异常的子类相关联。例如 -
class Super{
void a()throws IOException{
......
}
}
class Sub extends Super{
void a()throws IOException{
......
}
}
Sub类的a()方法必须抛出IOException或IOException的任何子类,否则编译器将显示错误。
这意味着如果你写
void a()throws Exception
在类Sub中,那么它将导致编译错误。
答案 3 :(得分:2)
易于记忆
此代码有效
public class A {
protected String foo() throws Exception{
return "a";
}
class B extends A {
@Override
public String foo() throws IOException{
return "b";
}
}
}
覆盖的foo方法具有公共访问权限,不受保护并抛出IOException异常的子代
此代码无效
public class A {
public String foo() throws IOException{
return "a";
}
class B extends A {
@Override
protected String foo() throws Exception{
return "b";
}
}
}
覆盖的foo方法具有更多限制访问修饰符并抛出异常,即IOException的子代
顺便说一句,你可以从超类覆盖方法而不是在所有
中抛出ecxeptions此代码有效
public class A {
public String foo() throws IOException{
return "a";
}
class B extends A {
@Override
public String foo(){
return "b";
}
}
}