Java 为什么必须在类定义中编写 throws 异常?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2008424/
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
Why do you have to write throws exception in a class definition?
提问by mrblah
Coming from C#, I just don't get this 'throws exception' that is written after a class/method definition:
来自 C#,我只是没有得到这个在类/方法定义之后编写的“抛出异常”:
public void Test() throws Exception
Do you have to write this? What if you don't? If I call a method that has this symbol, do I have to catch it?
你有必要写这个吗?如果你不这样做呢?如果我调用具有此符号的方法,是否必须捕获它?
采纳答案by delfuego
You don't haveto write it in all cases -- you just have to write it if your method throws a checked Exception
(an exception that is a subclass of Exception
and not a subclass of RuntimeException
). This is because your method signature is a contract, and it's declaring to all the code which calls it that it has the potential for throwing the given exception. Because it's a checked exception -- an exception which can be anticipated -- the calling code needs to anticipate the potential of seeing the exception thrown, and needs to be able to handle it.
您不必在所有情况下都编写它——您只需要在您的方法抛出已检查Exception
(一个属于 的子类Exception
而不是 的子类的异常)时编写它RuntimeException
。这是因为你的方法签名是一个契约,它向所有调用它的代码声明它有可能抛出给定的异常。因为它是一个已检查的异常——一个可以预期的异常——调用代码需要预测看到抛出的异常的可能性,并且需要能够处理它。
To answer your two specific questions:
要回答您的两个具体问题:
- do you have to write it/what if you don't: if your method throws a checked exception, then yes, you have to declare it in your method signature. If you don't, then your code won't compile.
- do you have to catch it: you have to do somethingwith it. The code calling the method can either catch it and handle it, it can catch it and re-throw it, or it can just pass it up the chain. In order to pass it up the chain, the code calling the method has to itself declare that it throws the same exception -- e.g., if method
bar
can throwSomeException
, and methodfoo
callsbar
and doesn't want to catch the exception, the method signature forfoo
would declare that it too throwsSomeException
.
- 你必须写它吗/如果你不写怎么办:如果你的方法抛出一个检查异常,那么是的,你必须在你的方法签名中声明它。如果不这样做,那么您的代码将无法编译。
- 你必须抓住它吗:你必须用它做点什么。调用该方法的代码可以捕获它并处理它,它可以捕获它并重新抛出它,或者它可以将它传递到链上。为了将它传递到链上,调用该方法的代码必须自己声明它抛出相同的异常——例如,如果方法
bar
可以抛出SomeException
,并且方法foo
调用bar
并且不想捕获异常,则方法签名为foo
会声明它也抛出SomeException
.
The Exceptions chapter of the Java lessonsis very good at explaining this in detail, and JavaWorld has a good article about throwing and catching exceptionsthat I've always found to be a good reference to pass onto folks.
Java 课程的Exceptions 一章非常擅长详细解释这一点,JavaWorld 有一篇关于抛出和捕获异常的好文章,我一直认为它是传递给人们的很好参考。
回答by danben
You have to write it in the case that the exceptions thrown are checked exceptions, which mean that it is the explicit responsibility of the caller to catch or rethrow the exception.
你必须在抛出的异常是检查异常的情况下编写它,这意味着捕获或重新抛出异常是调用者的明确责任。
回答by cyberconte
You don't have to throw the exception if you catch the exception in your code. If you don't catch it, it gets passed along to the caller, which is why you would need the throws clause.
如果在代码中捕获异常,则不必抛出异常。如果你没有抓住它,它就会被传递给调用者,这就是你需要 throws 子句的原因。
回答by Bob Cross
To answer your specific question, you almost never want to say throws Exception
per se.
要回答您的具体问题,您throws Exception
本身几乎不想说。
The throws
clause is notifying users of this method that there is an exceptional case that they will have to handle. For example, you might have an IOException
that results from some use of the file manipulating methods (e.g., unable to open the file in question). If you haven't handled that locally, you need to declare that your method throws
that exception back to the caller.
该throws
条款通知此方法的用户,他们必须处理一个特殊情况。例如,您可能会因IOException
使用某些文件操作方法(例如,无法打开有问题的文件)而导致结果。如果您尚未在本地处理该问题,则需要将您的方法声明throws
为该异常返回给调用者。
Modern IDEs will notify you that, for checked exceptions, you need to either handle them in your use of the method or throw them out of the method up the call tree (via the throws clause).
现代 IDE 会通知您,对于已检查的异常,您需要在使用方法时处理它们,或者将它们从调用树中的方法中抛出(通过 throws 子句)。
回答by Yishai
Basically yes, and if you don't your program won't compile. This is called a checked exception (Any exception is a checked exception unless it is or extends RuntimeException or Error).
基本上是的,如果你不这样做,你的程序将无法编译。这称为受检异常(任何异常都是受检异常,除非它是或扩展了 RuntimeException 或 Error)。
If there is anything in the method which throws an Exception it won't compile unless you either catch the exception or declare it on the method, and then anything calling that method will have to handle the Exception in the same manner.
如果方法中存在任何抛出异常的内容,它将不会编译,除非您捕获异常或在方法上声明它,然后调用该方法的任何内容都必须以相同的方式处理异常。
回答by Gaim
In C++ ( I can't C# but it is probably similar ) keyword throw
is a restriction for all of exception types so if there is no specification about throwing exceptions you can suppose that it can be whatever.
在 C++ 中(我不能使用 C#,但它可能类似)关键字throw
是对所有异常类型的限制,因此如果没有关于抛出异常的规范,您可以假设它可以是任何类型。
In Java you can suppose if there is no usage of keyword throws
then this method throws no one. ( you can be sure, but there needn't be runtime exceptions ). So if there is some specification about throwing you have to catch it of propagate it up
在 Java 中,您可以假设如果没有使用关键字,throws
则此方法不会抛出任何关键字。(您可以确定,但不一定有运行时异常)。所以如果有一些关于投掷的规范,你必须抓住它传播它
回答by Yoni
This concept of checked vs. unchecked exceptions doesn't exist in .net. The intentionof the original Java guru's was that if you have to declare the checked exceptions that you throw, so the caller will know that he/she has to catch them. for example, if you are dealing with the IO library, if forces you to catch the IOException.
.net 中不存在已检查与未检查异常的概念。该意向原始的Java大师的的是,如果你有,你扔了,所以调用者就知道他/她要追上他们申报检查的异常。例如,如果您正在处理 IO 库,则 if 会强制您捕获 IOException。
try {
file.delete();
} catch (IOException x) {
// do something
}
Unfortunately checked exceptions are over-used in Java (see spring philosophy). There is a lot of criticism about the abuse of checked exception and how they pollute the code. Libraries that throw checked exceptions more often than not lead the users to write code like this:
不幸的是,检查异常在 Java 中被过度使用(参见 spring哲学)。关于受检异常的滥用以及它们如何污染代码,有很多批评。经常抛出已检查异常的库会导致用户编写如下代码:
try {
file.delete();
} catch (IOException e) {
throw new RuntimeException(e);
}
If you are writing a library, consider whether your checked exception will hinder/annoy the user, and whether he/she benefits from having to catch them.
如果您正在编写一个库,请考虑您的检查异常是否会妨碍/惹恼用户,以及他/她是否因必须捕获它们而受益。
There are different school of thoughts on this matter, but the overwhelming trend today is to avoid checked exceptions (see successful projects like spring, hibernate, apache-commons, etc.).
关于这个问题有不同的思想流派,但今天的压倒性趋势是避免检查异常(参见成功的项目,如 spring、hibernate、apache-commons 等)。
I can attest that today I don't throw checked exceptions anymore. If it is really important that the user should know about the exception, then document it well in the javadocs, but give the user the freedom to write cleaner code.
我可以证明,今天我不再抛出已检查的异常。如果用户应该知道异常真的很重要,那么在 javadoc 中很好地记录它,但让用户可以自由地编写更清晰的代码。
EDIT: I found a similar question (and one of my previous answers) here. Maybe it will help.
编辑:我发现了一个类似的问题(我以前的答案之一)这里。也许它会有所帮助。
回答by Dusk
"throws" keyword is used if the exception may not gonna handle in current method and it can be propagated to the caller of that method.
如果异常可能不会在当前方法中处理并且可以传播到该方法的调用者,则使用“throws”关键字。
The caller can either handle that exception or propagate that exception to another method by using "throws" keyword.
调用者可以使用“throws”关键字处理该异常或将该异常传播到另一个方法。
The Exception class is base class for Runtime Exception.
Exception 类是 Runtime Exception 的基类。
回答by Waldemar Wosiński
Answer more to the topic rather to description: Class can not use "throws" keyword. Only methods and constructors can.
回答更多主题而不是描述:类不能使用“throws”关键字。只有方法和构造函数可以。
With little hack you can use throws on initialization block (but not static). You can set throws on constructor and then it will compile.
通过很少的技巧,您可以在初始化块上使用 throws(但不是静态的)。您可以在构造函数上设置 throws,然后它将编译。
public class Example{ // here you can not use throws
{
BufferedReader in = new BufferedReader(new FileReader("asdf"));
}
public AbstractWithConstantsOnly() throws FileNotFoundException { }
public static void main(String[] args) throws Exception {
new Example();
}
}