51

我正在为 Eclipse 使用 PMD 插件,使用System.out.println()说明时它给了我一个错误:

使用 System.(out|err).print,考虑使用记录器。

我的问题是 - 什么是记录器?它是如何打印到屏幕上的?为什么更好?

4

6 回答 6

35

请参阅log4j 的简短介绍

问题在于System.out用于打印调试或诊断信息。这是一种不好的做法,因为您无法轻松更改日志级别、将其关闭、自定义等。

但是,如果您合法System.out地用于向用户打印信息,则可以忽略此警告。

于 2010-05-01T14:47:50.377 回答
12

如果您使用 System.out|err.println(..) 在应用程序的 main() 方法中的控制台上打印出用户信息,那么您不会做错任何事。您可以通过插入注释“//NOPMD”来删除该消息。

System.out.println("Fair use of System.out.println(..).");// NOPMD

为此目的,PMD 违规大纲中有一个“标记为已审核”选项。

当然,您可以使用以下代码片段来欺骗 PMD:

PrintStream out=System.out;
out.println("I am fooling PMD.");  

在您的 main() 方法之外,请使用 Log-System,例如 Log4j。

更新:

您还可以修改 PMD 规则“SystemPrintln”以使用以下 XPath:

//MethodDeclaration[@MethodName!="main"]//Name[
starts-with(@Image, 'System.out.print')
or
starts-with(@Image, 'System.err.print')
] | //Initializer//Name[
starts-with(@Image, 'System.out.print')
or
starts-with(@Image, 'System.err.print')
]

这将忽略代码中任何名为“main”的方法中的 System.out.println 等,但在初始化代码中检查 System.out.println。我喜欢这个,因为从我的角度来看,System.out.println 在方法“main(String args[])”中是安全的。但是请谨慎使用,我必须检查在 AST 中 System.out.println 也可能出现的位置,并且必须适应 XPath。

于 2010-05-01T15:47:41.657 回答
7

Loggers 有多个级别的日志记录。

如果我们正在编写一个真正的短程序,仅仅为了学习目的System.out.println是可以的,但是当我们开发一个高质量的软件项目时,我们应该使用专业的记录器,并且应该避免 SOP。

专业的记录器提供不同级别的记录和灵活性。我们可以相应地获取日志消息。例如,X 组消息应仅在 PRODUCTION 上打印,Y 组消息应在 ERROR 上打印,等等。

我们在 中重定向消息的选项有限System.out,但对于记录器,您有提供多个选项的附加程序。我们甚至可以创建自定义输出选项并将其重定向到该选项。

于 2013-12-18T08:45:13.840 回答
6

此链接提供了有关如何使用 Log4j 的更简洁信息:不要使用 System.out.println!但是,它只有一个小缺陷,您不应该将库放入 中/jre/lib/ext,而应将其放入应用程序的运行时类路径中并一起发布。

优点是您可以使用日志记录级别来指示信息的重要性,以便您可以在外部配置要在输出中显示/隐藏的级别(这样您就不会被 - 毕竟 - 无用的信息所困扰) ,输出应该是什么样子(例如,包括时间戳、线程 ID、类名、方法名等)以及输出应该写入的位置(例如控制台、文件、电子邮件等)以及例如文件的情况还应该如何创建它们(例如按年、月和/或日分组)。

有几种记录器实现,如 Java SE 的 builtin java.util.logging.Logger、方便的Apache Commons Logging、流行的Apache Log4j、其后继Logback等。您可以使用Slf4j作为额外的抽象层,以便在需要时在任何这些记录器之间切换。

于 2010-05-01T14:55:20.503 回答
4

看来 PMD 假设您是System.out.println()出于调试目的而调用;诸如“我在你的方法中,正在执行你的 codez”之类的东西。

如果你这样做,你将有更好的时间写入像Log4J这样的记录器,因为它有多个流选项,而不仅仅是屏幕。

但是,如果您正在执行控制台应用程序并System.out作为其中的一部分进行调用,请忽略该警告。

于 2010-05-01T14:50:13.240 回答
1

System.out.println不好用,因为不能配置。相反,Logger可以配置为登录各个级别。它还有很多其他功能。

于 2010-05-01T14:54:34.187 回答