e.printStackTrace()对于未知异常有什么问题

时间:2011-05-02 10:08:28

标签: java logging exception-handling

如果我在已知异常的情况下使用记录器,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();
        }

6 个答案:

答案 0 :(得分:14)

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

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

在回答你的问题时,@ shinynewbike,我略微修改了我的答案。必须避免的是在不使用stderr功能的情况下将直接写入logger

loggers提供了按优先级和包更改日志记录跟踪的有用功能,除此之外,它们还允许将跟踪重定向到不同的输出机制......队列,文件,数据库,流......

当您直接写入System.errSystem.out时,您会失去这些功能,如果混合loggerSystem.err.write,最糟糕的情况可能会导致不同的'文件'将使您的系统调试变得困难。

答案 1 :(得分:5)

恕我直言,你应该

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

答案 2 :(得分:2)

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

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

使用日志库可以让您的应用程序灵活地将消息记录到可以由部署者配置的多个不同目的地。使用e.printStackTrace()时,您将无法获得此项好处。

你给btw的例子提出了一些其他问题。一些后续问题可能是:

  • catch(Exception ex)什么时候可以?
  • 何时/如何记录例外情况?

答案 3 :(得分:2)

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

e.printStackTrace()也没有做任何事情来描述导致错误的事情。您应该始终包含一条日志消息,该消息将使读取日志文件的人清楚地知道。

如果您将异常对象作为第二个参数发送,您将在日志文件中获得堆栈跟踪,以及异常的消息字符串。阅读日志文件的穷人很乐意提供这些信息。

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
}

答案 4 :(得分:1)

catch (Exception e)会抓住所有例外情况,即使是来自RuntimeException NullPointerExceptionIndexOutOfBoundsException {{1}}的未经检查的例外情况,该程序会继续运行,即使您极有可能不要那样,因为那些通常是致命的,可以在意想不到的位置退出控制流程。

如果您期望其中一个未经检查的异常,那么您应该明确捕获该类型的异常并处理它。

答案 5 :(得分:0)

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