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
overridden method does not throw exception
提问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
Graph
is an interface with all the methods of UNGraph
in it (the method getId()
doesn't have the throws
declaration 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 Exception
class). 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: IllegalArgumentException
or NullPointerException
, does not have to be included in a method signature, so you will alleviate your compiler error.
编译器发出错误,因为 Java 不允许您覆盖方法并添加已检查的异常(扩展Exception
类的任何用户定义的自定义异常)。因为很显然,要处理其中一些条件,该方案没有满足作为一个意外的发生(错误),你最好的选择就是抛出RuntimeException
。A RuntimeException
,例如: IllegalArgumentException
or 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 Graph
doesn't declare that it throws the checked exception NoSuchElementException
, so the compiler would allow this code without a try
block or a throws
clause 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 NoSuchElementException
or have the implementing class's method handle the NoSuchElementException
itself.
让接口的方法声明声明它抛出NoSuchElementException
或让实现类的方法处理它NoSuchElementException
本身。
回答by durron597
You have to declare the throws NoSuchElementException
in 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 中使用......使用不同的名称。