为什么我可以覆盖一些抛出异常的方法?

时间:2013-05-08 19:53:55

标签: java exception

我正准备自己进行测试,我发现这段代码我不明白。

如果我覆盖这样的方法,它就无法编译。好,可以。我必须在第2行抛出一个父异常,(比如抛出异常),它会工作得很好...... 但是,为什么有可能改变第7行 public void charlie抛出NullPointerException ??这样编译得很好,因为我仍然没有在第2行中抛出任何东西。

    1.public class A {
    2.  public void charlie() 
    3.  {
    4. 
    5.  }
    6.  class B extends A{
    7.      public void charlie() throws IOException
    8.      {}
    9.  }
    10.}

3 个答案:

答案 0 :(得分:8)

NullPointerException未经检查的例外(因为它扩展了RuntimeException)。它永远不需要声明,并且可以声明而不会影响其他任何内容。

您应该修改对已检查和未检查例外的理解。

Java exceptions tutorial可能是一个合理的起点。

答案 1 :(得分:1)

答案很简单: 如果A类中的原始方法不“支持”抛出它,则不能在B类覆盖methot中抛出异常。

假设您将从其他地方调用您的方法:

A a = new A();
a.charlie();

由于类charlie中的方法A会抛出任何异常,因此没问题。如果该方法会抛出异常,则必须编写

A a = new A();
try {
    a();
} catch(IOException ex) { //or any other exception
    //oh noes
}

但现在它变得复杂了,因为一种叫做类多态的东西会使你的工作模式变得复杂:

private A getA() {
    return new B(); //this will work since B extends A
}

private void doSomething() {
    A a = new A(); //you could also write A a = new B();
    a.charlie();
}

现在,此代码采用a,因为它是类A中的对象,并且方法charlie()没有抛出异常。尽管a是来自类B的对象,但是编译器不知道它并且不查看类B中的方法中抛出的异常,因为a来自等级A,至少从编纂者的角度来看。

这就是为什么类charlie()中的方法B必须与类A中的方法相同(输入参数,返回类型和抛出异常),您只能更改方法的主体。

但是,您仍然可以抛出NullPointerException或UnsuportedOperationException,因为它们属于RuntimeException,并且Java中的每个现有方法都会自动抛出RuntimeException,因此您可以随时抛出任何这些。

答案 2 :(得分:0)

IOException是一个必须抓住的例外;你不能在没有throws阻止的情况下调用try-catch的方法。

但是,现在考虑以下内容:

A myObject;
myObject = new B(); // legal - polymorphism
myObject.charlie();

有人可能会认为这不会引发错误,因为A没有throws声明,但B会声明{{1}}。因此,此代码不合法​​。

方法可能会声明更少的抛出异常,但更多