问题 System.out.println()内的toString()方法是双重调用?


我的一位教授曾说过以下代码永远不应该做:

的System.out.println(object.toString());

他说(我相信引用“有效的Java”)会导致双重调用。由于print语句调用对象的toString方法,因此将toString方法调用两次效率较低。首选方法是使用:

的System.out.println(对象);

显然,这种方式在代码中看起来更好,可以节省时间。无论怎样,我总会这样做,但我的问题是“这实际上更有效吗?”。在翻阅中 为PrintStream 文档,print方法已被重载以获取String作为参数(如果首先调用toString方法,则会出现这种情况)。我没有看到那个版本的print方法调用输入参数的toString方法,我不相信它会这样做有意义。

此外,对不起,如果这是重复。我找不到任何主题。


13034
2018-05-15 16:59


起源

+1好问题。好的研究。 - iamnotmaynard
更重要的是,打电话给 println 比打电话需要更多的时间 toString 这几乎是无关紧要的。 - assylias


答案:


不,它效率不高 - 正是因为你提到的过载。而且,一个电话 toString 在...上 String 非常快,所以即使没有过载,差异也是不可测量的。

但是,你的教授对于不打电话是正确的 System.out.println(object.toString());,但原因是不同的:由于调用是不必要的,代码的读者可能会感到困惑。


6
2018-05-15 17:01





您的示例在PrintStream中调用两种不同的方法。两个电话 toString() 最多一次。

  • 第一种方法是调用 println(String x), 哪一个 不打电话 x.toString()本身
  • 第二种方法是调用 println(对象x),这导致了一个电话 x.toString()如果x不为null。

但是,使用有潜在的优势 System.out.println(object)。如果 目的 为null,这将打印“null”。另一个语句抛出NullPointerException。


9
2018-05-15 17:08





在多线程环境中,调用System.out.println实际上已经足够糟糕,甚至比不必要的toString调用要糟糕得多。存在“问题”是因为你在“println”中有一个同步调用:

public void println() {
newLine();
}

private void newLine() {
try {
    synchronized (this) {
    ensureOpen();
...
}

所以,如果你正在尝试编写高效的java,你可以从避免它开始。作为替代方案,您可以使用任何不同的日志记录机制,例如 http://www.slf4j.org/


0
2018-05-15 17:55