Java 重写的方法不会抛出异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23526362/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 23:35:36  来源:igfitidea点击:

overridden method does not throw exception

javaexceptionmethodsoverriding

提问by user3613551

I have a problem when compiling my code, I'm trying to make a method of a class throw an personalized exception, given some conditions. But at the time of compiling I get the message:

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

Overridden method does not throw exception

重写的方法不抛出异常

Here's the class and exception declaration:

这是类和异常声明:

public class UNGraph implements Graph

Graphis an interface with all the methods of UNGraphin it (the method getId()doesn't have the throwsdeclaration on that script)

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

After the constructor I create the exception (inside the class UNGraph):

在构造函数之后,我创建了异常(在类 UNGraph 内):

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

Here is the method with the exception

这是除此之外的方法

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

Obviously I don't want the method to throw an exception every time, just when the condition is not met; and when it's met, I want to return a variable.

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

采纳答案by Sean Mickey

The compiler is issuing an error because Java does not allow you to override a method and add a checked Exception (any user-defined custom exception that extends the Exceptionclass). Because it is clear that you want to handle the scenario where some condition is notmet as an unexpected occurrence (a bug), your best option is to throw a RuntimeException. A RuntimeException, such as: IllegalArgumentExceptionor NullPointerException, does not have to be included in a method signature, so you will alleviate your compiler error.

编译器发出错误,因为 Java 不允许您覆盖方法并添加已检查的异常(扩展Exception类的任何用户定义的自定义异常)。因为很显然,要处理其中一些条件,该方案没有满足作为一个意外的发生(错误),你最好的选择就是抛出RuntimeException。A RuntimeException,例如: IllegalArgumentExceptionor NullPointerException,不必包含在方法签名中,因此您将减轻编译器错误。

I suggest the following changes to your code:

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

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

回答by rgettman

The problem becomes clear when you have such code as this using your class and interface:

当您使用类和接口拥有这样的代码时,问题就变得很清楚了:

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

The interface Graphdoesn't declare that it throws the checked exception NoSuchElementException, so the compiler would allow this code without a tryblock or a throwsclause on whatever method this code is in. But the overriding method clearly can throw the checked exception; it has declared as much. This is the reason that an overriding method cannot throw more checked exceptions than an overridden or abstract method. There would be a difference in how the calling code needs to handle checked exceptions, depending on the actual type of the object.

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

Have the interface's method declaration declare that it throws NoSuchElementExceptionor have the implementing class's method handle the NoSuchElementExceptionitself.

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

回答by durron597

You have to declare the throws NoSuchElementExceptionin all superclasses for a checked exception, if you want the subclasses to throw a checked exception in that method.

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

You can read more in the Java Language Specification:

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

11.2. Compile-Time Checking of Exceptions

The Java programming language requires that a program contains handlers for checked exceptions which can result from execution of a method or constructor. For each checked exception which is a possible result, the throws clause for the method (§8.4.6) or constructor (§8.8.5) must mention the class of that exception or one of the superclasses of the class of that exception (§11.2.3).

This compile-time checking for the presence of exception handlers is designed to reduce the number of exceptions which are not properly handled. The checked exception classes (§11.1.1) named in the throws clause are part of the contract between the implementor and user of the method or constructor. The throws clause of an overriding method may not specify that this method will result in throwing any checked exception which the overridden method is not permitted, by its throws clause, to throw (§8.4.8.3).

11.2. 异常的编译时检查

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

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



While I'm at it, you probably shouldn't use NoSuchElementException, as it's used in the JRE... use a different name.

当我在做的时候,你可能不应该使用NoSuchElementException,因为它在 JRE 中使用......使用不同的名称。