Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么';对于未知异常,e.printStackTrace()存在错误_Java_Logging_Exception Handling - Fatal编程技术网

Java 什么';对于未知异常,e.printStackTrace()存在错误

Java 什么';对于未知异常,e.printStackTrace()存在错误,java,logging,exception-handling,Java,Logging,Exception Handling,如果在已知异常的情况下使用记录器,未知异常的e.printStackTrace()有什么问题 我总是被告知不要这样做,但没有给出一个理由 下面的例子 try { dostuff(); } catch (AException ae) { logger.error("ae happened"); } catch (BException be) { logger.error("be happened

如果在已知异常的情况下使用记录器,未知异常的
e.printStackTrace()
有什么问题

我总是被告知不要这样做,但没有给出一个理由

下面的例子

try {
            dostuff();
        } catch (AException ae) {
            logger.error("ae happened");
        } catch (BException be) {
            logger.error("be happened");
        } catch (CException ce) {
            logger.error("ce happened");
        } catch (Exception e) {
            e.printStackTrace();
        }

因为它不使用记录器系统,所以它直接进入必须避免的
stderr

编辑:为什么必须避免直接写入stderr?

为了回答你的问题,@shinynewbike,我稍微修改了我的答案。必须避免的是直接将写入
stderr
,而不使用
记录器
功能

记录器
提供了有用的功能,可以按优先级和包更改日志记录跟踪,还允许将跟踪重定向到不同的输出机制。。。队列、文件、数据库、流

当您直接写入
System.err
System.out
时,您将失去这些功能,更糟糕的是,如果将
logger
System.err.write
混合使用,您可能会在不同的“文件”中得到跟踪,这将使调试您的系统变得困难。

  • 始终记录到记录器或标准错误,但不记录混合错误(这可能是投诉的原因)
  • 始终使用堆栈跟踪记录异常,除非您确定永远不会需要它

首先,打印堆栈跟踪无法解决问题,并且问题可能不会报告给父线程进行进一步处理。我的建议是处理catch子句中的异常,方法是使用e.getClass().getName()标识程序中的异常类型。

catch(异常e)
捕获所有异常,即使是从
RuntimeException
派生的未经检查的异常,如
NullPointerException
IndexOutOfBoundsException
,然后程序继续运行,即使您很可能不希望这样做,因为这些异常通常是致命的,并且可以随时退出控制流意外的位置


如果您希望出现这些未检查的异常,那么您应该显式地捕获该类型的异常并进行处理。

日志框架为您提供的一个功能是对日志消息的最终输出位置进行强大的抽象。您可能认为使用标准输出和标准错误可以实现同样的效果,但情况并非总是如此。在许多环境中,开发人员无法控制应用程序中标准io流的变化

最常见的情况是,您的应用程序在另一个容器(如tomcat)中运行,该容器可能会将自己的消息输出到standard out。由于您的应用程序正在同一进程中运行,因此您的所有消息将与容器中的消息以及在同一容器中运行的任何其他应用程序的消息混合在一起

通过使用日志库,您的应用程序可以灵活地将消息记录到多个不同的目的地,这些目的地可以由部署人员配置。如果使用
e.printStackTrace()
,您将无法获得此好处

顺便说一句,您给出的示例还提出了一些其他问题。一些后续问题可能是:

  • 什么时候可以捕获(例外情况除外)
  • 何时/如何记录异常

这是不好的,因为
e.printStackTrace()
不一定会写入与
logger.error()
相同的日志文件,因此为了保持一致性,您应该对所有内容使用
logger.error()

e.printStackTrace()
也没有描述导致错误的原因。您应该始终包含一条日志消息,让读取日志文件的人清楚地知道这一点

如果将exception对象作为第二个参数发送,您将在日志文件中获得堆栈跟踪以及异常的消息字符串。阅读日志文件的可怜的灵魂会很高兴得到这些信息

try {
    doStuff();
}
catch (AException ae) {

    // Send to the log file a message describing what we were doing,
    // and what happened as a result

    logger.error("ae happened, while attempting to do stuff, but that's okay", ae);

    dealWithTheSituation();
}
catch (Exception e) {

    logger.fatal("an unexpected error happened, while attempting to do stuff, cannot proceed", e);

    abortAndCatchFire();  // Burn the evidence
}

我想你是指
stderr
System.err
;)因为logger配置为监视它,所以没有人会看到stderr。@shinynewbike在新版答案中看到答案,希望它能澄清。这是一个很好的实用示例,9年后仍然适用