92

在我的应用程序中,我通过 PMD 运行我的代码。它向我显示了这条消息:

  • 避免 printStackTrace(); 改用记录器调用。

这意味着什么?

4

7 回答 7

158

这意味着您应该使用等日志框架,而不是直接打印异常:

e.printStackTrace();

您应该使用此框架的 API 记录它们:

log.error("Ops!", e);

日志框架为您提供了很大的灵活性,例如,您可以选择是否要记录到控制台或文件 - 或者如果您发现它们在某些环境中不再相关,则可以跳过一些消息。

于 2012-05-07T06:28:15.227 回答
45

如果您调用printStackTrace()异常,则跟踪将被写入,System.err并且很难将其路由到其他地方(或过滤它)。建议您不要这样做,而是使用日志框架(或围绕多个日志框架的包装器,如 Apache Commons Logging)并使用该框架(例如logger.error("some exception message", e))记录异常。

这样做可以让您:

  • 一次将日志语句写入不同的位置,例如控制台和文件
  • 按严重性(错误、警告、信息、调试等)和来源(通常基于包或类)过滤日志语句
  • 对日志格式有一定的影响,无需更改代码
  • 等等
于 2012-05-07T06:31:42.017 回答
17

生产质量程序应该使用许多日志记录替代方案之一(例如 log4j、logback、java.util.logging)来报告错误和其他诊断。这有很多优点:

  • 日志消息转到可配置的位置。
  • 最终用户看不到消息,除非您配置日志记录以便他/她看到。
  • 您可以使用不同的记录器和日志记录级别等来控制记录多少日志记录。
  • 您可以使用不同的附加程序格式来控制日志记录的外观。
  • 您可以轻松地将日志输出插入更大的监控/日志框架。
  • 以上所有操作都可以在不更改代码的情况下完成;即通过编辑已部署应用程序的日志记录配置文件。

相比之下,如果您只使用 printStackTrace,部署者/最终用户几乎没有任何控制权,并且日志消息可能会丢失或在不适当的情况下显示给最终用户。(没有什么比随机堆栈跟踪更能吓到胆小的用户了。)

于 2012-05-07T06:32:07.390 回答
6

在 Simple 中,e.printStackTrace() 不是一个好习惯,因为它只是将堆栈跟踪打印到标准错误。因此,您无法真正控制此输出的去向。

于 2017-09-12T09:11:12.830 回答
0

几乎每个日志框架都提供了一种方法,在该方法中我们可以将可抛出对象与消息一起传递。像:

public trace(Marker marker, String msg, Throwable t);

他们打印可投掷对象的堆栈跟踪。

于 2014-06-05T12:51:46.350 回答
-1

让我们从公司概念谈起。日志为您提供灵活的级别(请参阅logger.info 和 logger.debug 之间的区别)。不同的人希望看到不同的级别,例如 QA、开发人员、业务人员。但是 e.printStackTrace() 将打印出所有内容。此外,如果这个方法会被调用,同样的错误可能会打印多次。那么贵公司的 Devops 或 Tech-Ops 人员可能会发疯,因为他们会收到相同的错误提醒。我认为更好的替代品可能是log.error("errors happend in XXX", e) 这也将打印出比 e.printStackTrace() 更容易阅读的整个信息

于 2019-07-17T22:04:40.583 回答
-3

主要原因是 Proguard 会从生产环境中移除 Log 调用。因为通过记录或打印 StackTrace,可以通过例如 Logcat Reader 应用程序在 Android 手机中查看它们(堆栈跟踪或日志中的信息)。因此,这对安全性来说是一种不好的做法。此外,我们不会在生产过程中访问它们,最好从生产中删除。由于 ProGuard 删除了所有 Log 调用而不是 stackTrace,因此最好在 catch 块中使用 Log,并让 Proguard 将它们从生产中删除。

于 2018-07-04T00:01:09.133 回答