【问题标题】:overridden method does not throw exception被覆盖的方法不会抛出异常
【发布时间】:2023-03-21 17:27:01
【问题描述】:

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

被覆盖的方法不会抛出异常

这是类和异常声明:

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);
    }
}

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

【问题讨论】:

    标签: java exception methods overriding


    【解决方案1】:

    编译器发出错误,因为 Java 不允许您覆盖方法并添加已检查的异常(任何扩展 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);
    }
    

    【讨论】:

      【解决方案2】:

      当你有这样的代码使用你的类和接口时,问题就变得清晰了:

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

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

      让接口的方法声明声明它抛出NoSuchElementException,或者让实现类的方法自己处理NoSuchElementException

      【讨论】:

        【解决方案3】:

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

        您可以在Java Language Specification阅读更多内容:

        11.2。异常的编译时检查

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

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


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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-03-27
          • 1970-01-01
          • 2015-11-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多