重写方法不会抛出exception

编译我的代码时遇到问题,我试图让一个类的方法抛出一个个性化的exception,给定一些条件。 但在编译时我得到的信息是:

重写方法不会抛出exception

这是类和exception声明:

public class UNGraph implements Graph 

Graph是一个包含UNGraph所有方法的接口(方法getId()没有该脚本的throws声明)

在构造函数之后我创建了exception(在类UNGraph中):

 public class NoSuchElementException extends Exception { public NoSuchElementException(String message){ super(message); } } 

这是除例外的方法

 public int getId(....) throws NoSuchElementException { if (condition is met) { //Do method return variable; } else{ throw new NoSuchElementException (message); } } 

显然我不希望该方法每次都抛出exception,就在条件不满足时; 当它满足时,我想返回一个变量。

编译器发出错误,因为Java不允许您覆盖方法并添加已检查的Exception(任何扩展Exception类的用户定义的自定义exception)。 因为很明显你想要处理不满足某些条件作为意外事件(一个bug)的场景,你最好的选择就是抛出一个RuntimeExceptionRuntimeException (例如: IllegalArgumentExceptionNullPointerException )不必包含在方法签名中,因此您将减轻编译器错误。

我建议您对代码进行以下更改:

 //First: Change the base class exception to RuntimeException: public class NoSuchElementException extends RuntimeException { public NoSuchElementException(String message){ super(message); } } //Second: Remove the exception clause of the getId signature //(and remove the unnecessary else structure): public int getId(....) { if ( condition is met) { return variable; } //Exception will only be thrown if condition is not met: throw new NoSuchElementException (message); } 

使用类和接口获得此类代码时,问题就变得清晰了:

 Graph g = new UNGraph(); int id = g.getId(...); 

接口Graph没有声明它抛出已检查的exceptionNoSuchElementException ,因此编译器将允许此代码在没有try块或throws子句的情况下使用此代码的任何方法。但是重写方法显然可以抛出已检查的exception; 它已宣布同样多。 这就是为什么覆盖方法不能抛出比重写或抽象方法更多的已检查exception的原因。 调用代码需要如何处理已检查的exception,这取决于对象的实际类型。

让接口的方法声明声明它抛出NoSuchElementException或让实现类的方法处理NoSuchElementException本身。

如果希望子类在该方法中抛出已检查的exception,则必须在已检查exception的所有超类中声明throws NoSuchElementException

您可以在Java语言规范中阅读更多内容:

11.2。 编译时检查exception

Java编程语言要求程序包含可以由执行方法或构造函数导致的已检查exception的处理程序。 对于每个可能结果的已检查exception,方法(第8.4.6节 )或构造函数(第8.8.5节 )的throws子句必须提及该exception的类或该exception类的一个超类( §) 11.2.3 )。

对exception处理程序的存在进行编译时检查旨在减少未正确处理的exception数。 throws子句中命名的已检查exception类(第11.1.1节 )是方法或构造函数的实现者和用户之间的契约的一部分。 重写方法的throws子句可能没有指定此方法将抛出任何被抛出的方法不允许被抛出的方法抛出的任何已检查exception抛出( §8.4.8.3 )。


虽然我在这里,你可能不应该使用NoSuchElementException ,因为它在JRE中使用…使用不同的名称。