ToString() в System.out.println() двойной вызов?

Один мой профессор сказал, что следующий код никогда не должен выполняться:

System.out.println(Object.ToString());

Он сказал (и, я считаю, цитировал "Эффективная Java" ), он вызывает двойной вызов. Поскольку оператор print вызывает метод toString для объекта, было бы менее эффективным, чтобы метод toString вызывался дважды. Предпочтительным методом было бы просто использовать:

System.out.println(объект);

Очевидно, что этот способ выглядит лучше в коде и сэкономит время. Я всегда буду делать это так, несмотря ни на что, но мой вопрос: "Является ли это более эффективным?". При просмотре документации PrintStream метод печати был перегружен, чтобы взять параметр String в качестве параметра (это было бы так, если сначала был вызван метод toString), Я не вижу, где эта версия метода печати вызывает метод toString введенного параметра, и я не считаю, что для этого было бы разумно сделать это.

Кроме того, извините, если это дубликат. Я не мог найти на нем никаких тем.

Ответ 1

Нет, это не более эффективно - именно из-за перегрузки, о которой вы говорили. Более того, вызов toString на a String чрезвычайно быстрый, поэтому даже без перегрузки разница не будет измерима.

Однако ваш профессор прав насчет того, чтобы сделать вызов как System.out.println(object.toString());, но причина другая: поскольку вызов не нужен, читатели вашего кода могут запутаться.

Ответ 2

В примерах можно использовать два разных метода в PrintStream. Оба вызова toString() не более одного раза.

  • Первый метод вызывает println (String x), который не вызывает x.toString().
  • Второй метод вызывает println (Object x), что приводит к вызову x.toString(), если x не является нулевым.

Однако существует потенциальное преимущество использования System.out.println(object). Если объект имеет значение null, он печатает "null". Другой оператор генерирует исключение NullPointerException.

Ответ 3

в многопотоковой среде, вызывающей System.out.println, на самом деле достаточно плохо, даже намного хуже, чем ненужный вызов toString. "Проблема" существует, потому что у вас синхронный вызов внутри "println":

public void println() {
newLine();
}

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

Итак, если вы пытаетесь написать эффективную java, вы можете начать, избегая этого. В качестве альтернативы вы можете использовать любой из различных механизмов каротажа, например. http://www.slf4j.org/