我应该使用 System.out 还是 Log4j 来打印正常的信息?

Shall I use System.out or Log4j for normal information printout?

我是一个初学者 Java 程序员,有 2 年的经验。我正在为人类用户创建一个带有 Java 的小型 CLI 工具(不被服务器程序调用)。我的 Java 代码被我公司的代码气味检测工具标记了。该工具说我不应该使用 System.out,我应该考虑改用 Log4j。

我在 Internet 上搜索了很多,但几乎每个 post 都以类似“...System.out 的内容开头,但是,等等等等等等,所以你应该避免使用它".

他们怎么能假设 System.out 总是用于日志记录?甚至没有人提到任何其他可能的用例。

假设您正在为 Linux shell 开发一个新的 grep。您必须将模式匹配的结果打印给用户,对吗?我无法想象您会使用 Log4j 来做到这一点。

所以,简单地说,我是不是应该完全忘记 System.out?在Java中你会用什么来输出非日志信息?

当你开发一个规模大于 5 的更大的应用程序时。你必须使用一个框架来进行日志记录。让其他人更容易找到问题的根源很重要。

System.out 您可以在非常小的应用程序或小型团队中使用,在这些地方您可以进行基础交流,但不推荐这样做,因为您希望查看日志来推理应用程序崩溃的原因以及相应的数据而不是控制台打印outs 说有问题,但你不知道 class 发生了什么,因为你的队友编码了那个特定的 class.

首先,System.out 不是记录输出的目标,除了非常小的工具或一些一次性的东西;这就是发明日志框架的原因。首先,无论您选择 Log4J、JDK 日志记录还是完全不同的东西,这并不重要。尽管 Log4J 已成为 Java 世界中日志记录的事实标准。

由于那些“代码气味检测器”总是假设(除非另有通知)您编写了某种服务器软件,因此当您使用输出到 System.out 时它们会发出警告,因为对于这样的服务器,它通常不会打印到 System.out/dev/nul 的区别...

但是如果你写了某种命令行工具(也许是服务器的批处理客户端,只是为了有另一个例子而不是 grep ......),将当前状态或其他输出写入 System.out(即使“气味嗅探器”仍在呻吟)。 “状态”在这里主要是指正反馈;任何错误消息仍应记录到日志子系统中,尽管将它们也打印到屏幕上仍然是个好主意。

通常您可以注释您的源代码以安抚“气味检测器”……

这是一个代码异味问题,但日志记录可能不是首选的替代方法。我宁愿接受一个流参数来简化单元测试的编写。例如:

public class Greeter {

    public void greet(String name, PrintWriter out) {
        out.print("Hello, " + name);
    }

}

public class GreeterProgram {

    public static void main(String[] args) {
        new Greeter().greet(args[0], new PrintWriter(System.out));
    }

}

public class GreeterTest {

    @Test
    public void testGreet() {
        StringWriter sw = new StringWriter();
        PrintWriter out = new PrintWriter(sw);
        new Greeter().greet("Zhou", out);
        out.flush();
        assertEquals("greeting", "Hello, Zhou", sw.toString());
    }
}