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