致命错误 vs 异常

3

我知道Error[运行时错误]和Exception之间的区别。{参考JAVA语言}。 但致命错误和异常是相同的还是不同的?或者在Java中根本没有致命错误这个概念? 我在谷歌上搜索,但结果令人困惑。


2
你确定你知道ErrorException之间的区别吗?因为有一个RuntimeException,所以如果你认为Error在某种程度上是特定于运行时的,那么你就错了。 - Kayaman
java.lang.Error 和 java.lang.Exception 类都是 java.lang.Throwable 类的子类,但它们之间存在一些显著的区别。java.lang.Error 类表示主要由应用程序运行环境引起的错误。例如,当 JVM 内存不足时出现 OutOfMemoryError,当堆栈溢出时出现 StackOverflowError。 - user6134582
2
不存在所谓的“致命”错误和“非致命”错误之分,异常也可能是致命的。这取决于它们如何被处理(或未被处理),以及该错误/异常是否导致JVM终止。请注意,通常不应捕获错误;有些异常应该被捕获。 - Andy Turner
2个回答

10

阅读Java异常教程

如果需要简短的解释,您可以使用此小指南。查看带有Java异常层次结构(红色)和每个类别中的几个示例(蓝色)的类图。

enter image description here

Throwable:Java异常机制可抛出(和捕获)的所有内容的共同祖先。

Error:您可以将Error视为所谓的“致命异常”。通常甚至没有意义尝试恢复应用程序。 OutOfMemoryErrorStackOverflowError是此类致命错误,你几乎无法在应用程序内做任何操作。

不要捕获Error,让程序崩溃并在外部解决问题。

RuntimeException:应该用于大部分程序员错误(请参见以下示例),例如未处理的空指针取消引用、未满足方法合同等。

虽然有一些技术将所有异常捆绑到RuntimeException中,并在业务代码外部处理它们(通常使用AOP),但通常出现RuntimeException的情况意味着您应该让程序崩溃并修复其源代码。

/**
 * Does something with s.
 * @param s The input string
 */
public void badlyDesignedMethod(String s) {
    // Here the programmer omitted to check s against null
    int i = s.length();
    ...
}

/**
 * Does something with s.
 * @param s The input string; must not be null
 */
public void betterDesignedMethod(String s) {
    if (s == null) {
        throw new IllegalArgumentException("The parameter s must not be null!");
    }
    int i = s.length();
    ...
}

public void caller() {
    badlyDesignedMethod(null); // will throw NullPointerException
    // It is the fault of the programmer of badlyDesignedMethod()
    // as they have not specified that the parameter must not be null.

    betterDesignedMethod(null); // will throw IllegalArgumentException
    // Now it is the fault of the programmer of caller()
    // as they violated the contract of betterDesignedMethod()
    // which DOES tell them that the parameter must not be null
}

ErrorRuntimeException都是未检查异常,这意味着方法无需声明它们会抛出异常,调用者也不需要捕获它们,即无需使用try-catch块来包围调用。

其他异常(从Exception继承而来,而不是RuntimeException继承):这些异常应该被声明throws...)并且需要被捕获try-catch),通常用于从方法向其调用者传递有用信息的情况,例如数据库不可用、文件无法打开等等。

这些异常需要由您的代码处理。它们是“预期异常”,与“运行时异常”相比属于“预料之中的异常”。

public void doSomethingWithFile(String fileName) throws IOException {
    if (/* file is not accessible */) {
        throw new IOException("File " + fileName + " is not accessible!");
    }
    ...
}
public void caller() {
    try {
        doSomethingWithFile("/home/honza/file.txt");
    }
    catch (IOException e) {
        // handle the fact that the file is not accessible
        return;
    }
    ...
}

1
“FATAL”一词通常用于日志框架的上下文中,例如log4j、SLF4J、logback等。现在,在查看日志文件时,可以找到像“FATAL”这样的消息。
2015-09-28 15:21:48,222 Thread-4 FATAL Unable to register shutdown hook because JVM is shutting down. java.lang.IllegalStateException: Cannot add new shutdown hook as this is not started. Current state: STOPPED
at org.apache.logging.log4j.core.util.DefaultShutdownCallbackRegistry.addShutdownCallback(DefaultShutdownCallbackRegistry.java:113)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.addShutdownCallback(Log4jContextFactory.java:271)
at org.apache.logging.log4j.core.LoggerContext.setUpShutdownHook(LoggerContext.java:240)     

这表示某个操作导致了错误或异常,并且开发人员使用FATAL级别的日志框架记录了该错误或异常。消息可以在任何级别记录。
例如,Log4J提供许多日志级别:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、ALL。

http://logging.apache.org/log4j/2.x/log4j-api/apidocs/org/apache/logging/log4j/Level.html

仅仅为了更加混淆,还有一种叫做ERROR的日志级别。

总之,FATAL异常与FATAL错误: FATAL是异常或错误对象记录的日志级别,并不影响发生的异常或错误,但当开发人员以FATAL级别记录时,它是用来引起注意并引起反应的。 根据Log4J关于何时记录FATAL级别的文档, “一个严重的错误将会阻止应用程序继续运行。”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接