记录器与 System.out.println
Posted
技术标签:
【中文标题】记录器与 System.out.println【英文标题】:Logger vs. System.out.println 【发布时间】:2011-02-14 13:46:12 【问题描述】:我正在为 Eclipse 使用 PMD 插件,但在使用 System.out.println()
时它给了我一个错误的解释:
使用System.(out|err).print,考虑使用记录器。
我的问题是 - 什么是记录器?它是如何打印到屏幕上的?为什么更好?
【问题讨论】:
另见这个最近的问题:***.com/questions/2746578/advantage-of-log4j 【参考方案1】:见this short introduction to log4j。
问题在于使用System.out
打印调试或诊断信息。这是一种不好的做法,因为您无法轻松更改日志级别、将其关闭、自定义等。
但是,如果您合法地使用System.out
向用户打印信息,那么您可以忽略此警告。
【讨论】:
我会将答案扩展为“[...] 将信息打印给用户或其他进程,然后您可以忽略此警告”。想想 Unix 进程将输出通过管道传输到另一个,正是System.out
的概念赋予了这一点。【参考方案2】:
如果您在应用程序的 main() 方法中使用 System.out|err.println(..) 在控制台上打印用户信息,那么您不会做错任何事。您可以通过插入注释“//NOPMD”来删除该消息。
System.out.println("Fair use of System.out.println(..).");// NOPMD
为此目的,PMD 违规大纲中有一个“标记为已审核”选项。
当然你可以用下面的代码 sn-p 来欺骗 PMD:
PrintStream out=System.out;
out.println("I am fooling PMD.");
在你的 main() 方法之外使用一个日志系统,例如 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。
【讨论】:
【参考方案3】:Loggers 有多个级别的日志记录。
如果我们正在编写一个真正的短程序,仅用于学习目的System.out.println
可以,但是当我们开发高质量的软件项目时,我们应该使用专业的记录器,并且应该避免 SOP。
专业的记录器提供不同级别的记录和灵活性。我们可以相应地获取日志消息。例如,X 组消息应仅在 PRODUCTION 上打印,Y 组消息应在 ERROR 上打印,等等。
我们在System.out
中重定向消息的选项有限,但对于记录器,您有提供多个选项的附加程序。我们甚至可以创建一个自定义输出选项并将其重定向到该选项。
【讨论】:
【参考方案4】:此链接提供了有关如何使用 Log4j 的更简洁信息:Don't use System.out.println! 但是它只有一个小缺陷,您不应该将库放在 /jre/lib/ext
中,而是将其放在应用程序的运行时类路径中并发布一起来。
优点是您可以使用日志记录级别来指示信息的重要性,以便您可以在外部配置在输出中显示/隐藏哪些级别(这样您就不会被 - 毕竟 -无用信息),输出应该是什么样子(例如,包括时间戳、线程 ID、类名、方法名等)以及输出应该写入到哪里(例如控制台、文件、电子邮件等)以及在以下情况下例如文件还应该如何创建它们(例如按年、月和/或日分组)。
有几种记录器实现,如 Java SE 的内置 java.util.logging.Logger
、方便的 Apache Commons Logging、流行的 Apache Log4j、其后继 Logback 等。您可以使用 Slf4j 作为额外的抽象层来切换在任何需要时在这些记录器之间进行。
【讨论】:
【参考方案5】:似乎 PMD 假设您正在调用 System.out.println()
以进行调试;诸如“我在你的方法中,正在执行你的 codez”之类的东西。
如果你这样做,你将有更好的时间写入像 Log4J 这样的记录器,因为它有多个流选项,而不仅仅是屏幕。
但是,如果您正在执行控制台应用程序并在其中调用 System.out
,请忽略该警告。
【讨论】:
【参考方案6】:System.out.println
不好用,不能配置。相反,Logger
可以配置为登录各个级别。它还有很多其他功能。
【讨论】:
以上是关于记录器与 System.out.println的主要内容,如果未能解决你的问题,请参考以下文章