在Java中使用System.err有什么问题?

时间:2009-06-26 15:34:21

标签: java static-analysis stderr

我在我的Java代码上使用了Enerjy(http://www.enerjy.com/)静态代码分析器工具。它告诉我以下一行:

System.err.println(“忽略该数据库”);

很糟糕,因为它使用System.err。确切的错误是:“JAVA0267使用System.err”

使用System.err有什么问题?

7 个答案:

答案 0 :(得分:22)

简短回答:将它用于记录目的被认为是一种不好的做法。

观察到,在过去没有广泛可用/接受的日志框架的情况下,每个人都使用System.err来打印错误消息并将跟踪堆栈到控制台。这种方法在开发和本地测试阶段可能是合适的,但不适合生产环境,因为您可能会丢失重要的错误消息。因此,在今天的几乎所有静态分析工具中,都会检测到这种代码并将其标记为不良实践(或类似命名的问题)。

日志框架反过来提供了记录事件和错误消息的结构化和逻辑方式,因为它们可以将消息存储在各种持久位置(日志文件,日志数据库等)。

最明显(并且没有外部依赖关系) hack 解决方案是通过java.util.logging.Logger类使用内置的Java Logging框架,因为它默认情况下将日志记录事件转发到控制台。例如:

final Logger log = Logger.getLogger(getClass().getName());
...
log.log(Level.ERROR, "Something went wrong", theException);

(或者您可以关闭该分析选项)

答案 1 :(得分:7)

您的错误描述符是:

  

使用System.err可能表示残留的调试或样板代码。考虑使用   全功能的日志包,如Apache Commons,用于处理错误记录。

您似乎正在使用System.err进行日志记录,但由于以下几个原因,这是次优的:

  • 在不修改应用程序二进制文件的情况下,无法在运行时启用日志记录
  • 无法通过编辑配置文件来控制日志记录行为
  • 可能很多其他人

答案 2 :(得分:7)

虽然我同意上面关于使用日志记录框架的观点,但我仍倾向于在一个地方使用System.err输出:在关闭挂钩中。这是因为我发现在使用java.util.logging框架时,如果它们出现在关闭挂钩中,则不会始终显示日志语句。这是因为日志库可能包含自己的关闭挂钩来清理日志文件和其他资源,并且由于您不能依赖关闭挂钩运行的顺序,因此您不能依赖java.util.logging语句按预期工作

查看此链接(“评论”部分)以获取更多相关信息。

http://weblogs.java.net/blog/dwalend/archive/2004/05/shutdown_hooks_2.html

(显然另一种选择是使用不同的日志框架。)

答案 3 :(得分:2)

System.err实际上更多用于调试目的。正确的异常处理和以更加用户友好的方式处理错误是首选。如果用户想要查看错误,请改为使用System.out.println。

如果您想从开发人员的角度跟踪这些错误,您应该使用记录器。

答案 4 :(得分:1)

写入System.err的内容通常在运行时丢失,因此使用更灵活的输出消息的日志框架被认为是更好的做法,因此可以将其存储为文件并进行分析。 / p>

非控制台应用程序的System.err和System.out只能由在他或她的IDE中运行代码的开发人员看到,如果在生产中触发该项,有用的信息可能会丢失。

答案 5 :(得分:1)

System.err.println和System.out.println不应该用作loggging-interface。 STD-Output和STD-Error(由System.out和.err编写)用于来自命令行工具的消息。

答案 6 :(得分:0)

System.err打印到控制台。这可能适合学生测试他们的作业,但不适合不能看到这些消息的应用程序(控制台只存储这么多行)。

更好的方法是抛出一个异常,保存通常会发送到控制台的消息。另一种方法是使用第三方记录软件将这些消息存储在一个可以永久存储的文件中。