java catch 块是否能够捕获 Throwable(错误和异常)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6772225/
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
Is catch block able to catch Throwable (both error and exception)
提问by Romi
In one of my interview, they asked me, is it possible to write Throwable in catch() like this
在我的一次采访中,他们问我,是否可以像这样在 catch() 中编写 Throwable
try{
some code
}
catch(Throwable t)
{
}
I said yes. it will not give a compile time error but jvm would not handle it if there occur an Error
(sub class of Throwable ), since Errors are irreversible conditions that can not be handled by jvm. than they further asked than what is the use of writing Throwable .
我说是。它不会给出编译时错误,但如果出现Error
( Throwable 的子类),jvm 将不会处理它,因为错误是无法由 jvm 处理的不可逆条件。比他们进一步问比写Throwable有什么用。
Please give me proper reply can we use Throwable in catch. if yes why.
请给我正确的答复,我们可以在 catch 中使用 Throwable。如果是为什么。
回答by home
It is possible to catch Throwable
. And yes, you will also catch instances of java.lang.Error
which is a problem when it comes to e.g. OutOfMemoryError
's. In general I'd not catch Throwable
's. If you have to, you should do it at the highest place of your call stack, e.g. the main
method (you may want to catch it, log it, and rethrow it).
有可能抓到Throwable
。是的,java.lang.Error
当涉及到 eg 时,您也会发现有问题的实例OutOfMemoryError
。一般来说,我不会赶上Throwable
的。如果必须,您应该在调用堆栈的最高位置执行此操作,例如main
方法(您可能想要捕获它、记录它并重新抛出它)。
I agree with your argumentation, it does not make sense to catch events you're not able to handle (e.g. OutOfMemoryError). A nice post is here.
我同意您的论点,捕获您无法处理的事件(例如 OutOfMemoryError)是没有意义的。一个不错的帖子在这里。
回答by Stephen C
Yes it is possible to catch Throwable
.
是的,有可能赶上Throwable
。
Whether the JVM / application will be able to continue if you catch an error depends on the actual error that occurred, what caused it, and what (if anything) your application does next.
如果您发现错误,JVM/应用程序是否能够继续取决于实际发生的错误、导致错误的原因以及您的应用程序接下来要做什么(如果有的话)。
In some cases, the JVM may be in such a bad way that no recovery is possible.
In some cases, the JVM is fine ... as long as you don't do certain things. Class loading errors are a good example. If your application doesn't attempt to use the class or dependent classes that you failed to load, you should be fine to continue. (In reality, applications are not designed to continue without classes that fail to load ... but if it was, it could.)
In some cases, the core JVM will be fine, but unspecified damage could have been done to the application's data structures, and/or to its threads and computation state. OOMEs are liable to do this to you, especially if your application is not designed to deal with threads that die unexpectedly.
Catching and recovering from OOMEs is problematic for another reason. While the termination of the current computation will free up some heap space, there's a good chance that it won't free up enoughspace. So you can easily get into a situation where your application is repeatedly throwing and catching lots of OOMEs, and making no real progress.
在某些情况下,JVM 可能处于非常糟糕的状态,以至于无法恢复。
在某些情况下,JVM 很好……只要您不做某些事情。类加载错误就是一个很好的例子。如果您的应用程序没有尝试使用您未能加载的类或依赖类,您应该可以继续。(实际上,应用程序并不是为了在没有加载失败的类的情况下继续运行而设计的……但如果是这样,它也可以。)
在某些情况下,核心 JVM 没有问题,但可能对应用程序的数据结构和/或其线程和计算状态造成了未指明的损坏。OOME 很容易对你这样做,特别是如果你的应用程序不是为了处理意外死亡的线程而设计的。
由于另一个原因,从 OOME 中捕获和恢复是有问题的。虽然当前计算的终止会释放一些堆空间,但很有可能不会释放足够的空间。因此,您很容易陷入应用程序反复抛出和捕获大量 OOME 而没有取得实际进展的情况。
All of this means that it is generally a bad idea to try to recover from errors. And that's in line with what the javadoc for error says:
所有这些都意味着尝试从错误中恢复通常是一个坏主意。这与 javadoc for error 所说的一致:
"An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch."
“一个错误是 Throwable 的一个子类,它表明一个合理的应用程序不应该试图捕捉的严重问题。”
回答by Premraj
- Yes we can catch
Throwable
but as best practice, it is not advised to catchThrowable
. - Catching
Throwable
includesErrors
too, we should not catch errors, it helps to identify JVM issues.
- 是的,我们可以捕捉,
Throwable
但作为最佳实践,不建议捕捉Throwable
。 - 捕获也
Throwable
包括Errors
,我们不应该捕获错误,它有助于识别 JVM 问题。
回答by Michael Rutherfurd
Catching Throwable will catch all Exceptions (including RuntimeExceptions) and all Errors. It is not recommended to catch any of the parent Throwables (Throwable, Error, Exception or RuntimeException) but it is not uncommon to find this if a method throws too many checked exceptions or throws Exception.
捕获 Throwable 将捕获所有异常(包括运行时异常)和所有错误。不建议捕获任何父 Throwables(Throwable、Error、Exception 或 RuntimeException),但如果一个方法抛出太多已检查的异常或抛出异常,发现这种情况并不少见。
It is not uncommon in certain APIs to document a method as throws Exception. This provides some flexibility at the expense of control. I like to define a new Exception class to handle this sort of case but that is personal preference.
在某些 API 中,将方法记录为 throws Exception 的情况并不少见。这以牺牲控制为代价提供了一些灵活性。我喜欢定义一个新的 Exception 类来处理这种情况,但这是个人喜好。
The following simple class shows samples of the throwable types and corresponding catch blocks.
下面的简单类显示了 throwable 类型和相应的 catch 块的示例。
public class ThrowableExamples {
public static void main(String[] args) {
try {
// throw new NoSuchMethodException("Exception");
// throw new Exception("Exception");
// throw new IllegalStateException("RuntimeException");
// throw new RuntimeException("RuntimeException");
throw new NoSuchMethodError("Error");
// throw new Error("Error");
// throw new Throwable("Throwable");
} catch (RuntimeException e) {
System.out.println("Caught RuntimeException: " + (e.getMessage().equals("RuntimeException") ? "Expected" : "Unexpected"));
} catch (Exception e) {
System.out.println("Caught Exception: " + (e.getMessage().equals("Exception") ? "Expected" : "Unexpected"));
} catch (Error e) {
System.out.println("Caught Error: " + (e.getMessage().equals("Error") ? "Expected" : "Unexpected"));
} catch (Throwable e) {
System.out.println("Caught Throwable: " + (e.getMessage().equals("Throwable") ? "Expected" : "Unexpected"));
}
}
}
回答by Dmitriy R
Throwable can be used instead of any individual exception/error. However it is recommended to pass through ThreadDeadException. So you can add extra catch clause for it, or filter by type.
可以使用 Throwable 代替任何单独的异常/错误。但是建议通过 ThreadDeadException。所以你可以为它添加额外的 catch 子句,或者按类型过滤。