重写方法不会抛出异常

时间:2014-05-07 19:15:09

标签: java exception methods method-overriding

编译代码时遇到问题,我尝试在某些条件下尝试让类的方法抛出个性化异常。但在编译时我收到了消息:

  

重写方法不会抛出异常

这里是类和异常声明:

public class UNGraph implements Graph

Graph是一个包含UNGraph所有方法的界面(方法getId()在该脚本上没有throws声明)

在构造函数之后我创建了异常(在类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);
    }
}

显然,我不希望这种方法每次都抛出异常,就在条件不满足的时候;当它遇到时,我想返回一个变量。

3 个答案:

答案 0 :(得分:11)

编译器发出错误,因为Java不允许您覆盖方法并添加已检查的Exception(任何扩展Exception类的用户定义的自定义异常)。因为很明显你想要处理某些条件遇到意外事件(一个错误)的情况,你最好选择抛出一个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);
}

答案 1 :(得分:0)

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

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

接口Graph未声明它会抛出已检查的异常NoSuchElementException,因此编译器将允许此代码不带try块或throws子句这个代码所处的方法是什么。但是重写方法显然可以抛出已检查的异常;它已宣布同样多。这就是重写方法不能抛出比重写或抽象方法更多的已检查异常的原因。调用代码需要处理检查异常的方式会有所不同,具体取决于对象的实际类型。

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

答案 2 :(得分:0)

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

您可以在Java Language Specification

中阅读更多内容
  

11.2。编译时检查例外

     

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

     

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


虽然我在这,但您可能不应该使用NoSuchElementException,因为它是used in the JRE ...使用不同的名称。