Java 为什么我可以覆盖一些抛出异常的方法,而我不能覆盖其他方法?

Java 为什么我可以覆盖一些抛出异常的方法,而我不能覆盖其他方法?,java,exception,Java,Exception,我正在准备一个测试,我发现这个代码我不懂 如果我像这样重写一个方法,它就无法编译。好吧,很公平。我必须在第2行中抛出一个父异常(比如抛出异常),它可以正常工作。。。 但是,为什么有可能将第7行更改为 public void charlie抛出NullPointerException??这将很好地编译,因为我仍然没有在第2行中抛出任何内容 1.public class A { 2. public void charlie() 3. { 4. 5.

我正在准备一个测试,我发现这个代码我不懂

如果我像这样重写一个方法,它就无法编译。好吧,很公平。我必须在第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.}

NullPointerException
是未经检查的异常(因为它扩展了
RuntimeException
)。它永远不需要声明,并且可以在不影响任何其他内容的情况下声明

您应该修改对已检查和未检查异常的理解


这可能是一个合理的起点。

NullPointerException
是一个未经检查的异常(因为它扩展了
RuntimeException
)。它永远不需要声明,并且可以在不影响任何其他内容的情况下声明

您应该修改对已检查和未检查异常的理解


这可能是一个合理的起点。

IOException
是一个必须捕获的异常;如果没有
try catch
块,则不能调用
抛出它的方法

然而,现在考虑以下内容:

A myObject;
myObject = new B(); // legal - polymorphism
myObject.charlie();
人们可能认为这不会引发错误,因为
A
没有
throws
声明,但是
B
有。因此,此代码不合法


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

IOException
是一个必须捕获的异常;如果没有
try catch
块,则不能调用
抛出它的方法

然而,现在考虑以下内容:

A myObject;
myObject = new B(); // legal - polymorphism
myObject.charlie();
人们可能认为这不会引发错误,因为
A
没有
throws
声明,但是
B
有。因此,此代码不合法

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

答案很简单: 若类A中的原始方法不“支持”抛出异常,则不能在类B中的overwriten method中抛出异常

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

A a = new A();
a.charlie();
因为类
A
中的方法
charlie
不会抛出任何异常,所以可以。如果该方法将引发异常,则必须编写

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
,至少从编译器的角度看是这样

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

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

答案很简单: 若类A中的原始方法不“支持”抛出异常,则不能在类B中的overwriten method中抛出异常

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

A a = new A();
a.charlie();
因为类
A
中的方法
charlie
不会抛出任何异常,所以可以。如果该方法将引发异常,则必须编写

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
,至少从编译器的角度看是这样

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


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

没错,IOException是一个选中的异常,因此需要建立一个策略,而NullPointerException则是一个未经检查的异常,因此它不需要:没错,IOException是一个已检查的异常,因此它需要建立一个策略,而NullPointerException是一个未检查的异常,因此它不需要。:)