Java是否默认声明“抛出exception”?

考虑以下课程:

class X { public void met() { } } 

 class Y extends X { public void met() throws NullPointerException { throw new NullPointerException(); } } 

从我在其他问题上阅读的内容( 为什么不能覆盖方法抛出比重写方法更广泛的exception?和抛出exception的Java方法 )

我理解子类中的重写方法必须抛出重写方法中抛出的exception的相同或子类。

Java方法总是抛出exception类型的exception吗?

…换句话说,编译器添加抛出exception

所以X类看起来像这样

 class X { public void met() throws Exception { } } 

我想澄清一下,我并没有错误地总是添加默认exception处理程序Exception。

相关问题:

IOException与RuntimeException Java

有两种类型的exception:checked Exceptions(如解析文本时的ParseException )和未经检查的exception(如NullPointerException )。

必须在方法签名中声明已检查的例外。 可以在方法签名中声明未经检查的exception。

当重写方法(来自接口或超类)时,您只需指定实例中的exception即可。 您不能声明在重写方法中不允许的实现中抛出已检查的exception。

这是允许的:

 class X { void someMethod() } class Y extends X { @Override void someMethod() throws UncheckedException } 

这是不允许的:

 class X { void someMethod() } class Y extends X { @Override void someMethod() throws CheckedException } 

这也是允许的:

 class X { void someMethod() throws CheckException } class Y extends X { @Override void someMethod() } 

slartidan在回答中说的是完全正确的。 再解释一下:

如果在方法体内抛出“Checked Exception” ,则需要处理它(使用catch块)或声明throws-clause

重申之前链接的JLS:

  1. Exception是一个扩展 Throwable的类
  2. Error也是一个扩展 Throwable的类
    • 通常不应该发现错误,因为它们表明存在严重问题。 (例如OutOfMemoryError
    • 捕获Exception不会捕获错误
  3. 还有RuntimeException 。 这是一个扩展Exception的类

编译时 不会检查错误和运行时exception,因为这正是“已检查exception”的含义。

您可以在代码中的任何位置抛出Error s和RuntimeException

现在这如何影响throws子句:

throws子句指定对声明的方法的调用可能导致指定的exception。 有趣的是抛出期望一个Throwable ,这使得以下声明有效:

 public void method() throws StackOverflowError, NullPointerException { //... } 

在throws子句中声明未检查的exception时没有编译器效果,但有时为了进一步明确源代码而这样做。

另外,JavaDoc中有时会提到这样的exception(例如BigInteger#divide

但是,当重写方法时,编译器会检查throws子句。 当覆盖方法时,它有点类似于可见性规则。 这意味着可以始终执行抛出未经检查的exception(并声明相应的throws子句)。 以下声明有效:

 public interface Demo { void test(); } public class DemoImpl implements Demo { public void test() throws NullPointerException { throw new NullPointerException(); } } 

反过来也是如此。 throws子句中未经检查的exception会被编译器忽略,因为它们与编译时检查无关:

 public interface Demo { void test() throws NullPointerException; } public class DemoImpl implements Demo { public void test() { throw new NullPointerException(); } } 

throws-clauseinheritance的一般规则是:一个接口来统一它们:接口必须声明所有可以通过实现类抛出的已检查exception。 或者换句话说:

实现类可以在实现方法的throws-clause中的接口方法的throws-clause中声明声明的已检查exception的子集

这意味着以下有效:

 public interface Demo { void test() throws IOException, ParseException; } public class DemoImpl implements Demo { public void test() throws IOException { throw new IOException(); } } 

什么是无效的是在实现方法的throws-clause中声明一个未在相应的接口方法子句中声明的已检查exception:

 public interface Fail { void test() throws ParseException; } public class FailImpl implements Fail { public void test() throws IOException { throw new IOException(); } }