Почему toString() в экземпляре объекта (который является нулевым) не бросает NPE?
Рассмотрим ниже:
Object nothingToHold = null;
System.out.println(nothingToHold); // Safely prints 'null'
Здесь Sysout должен ожидать String.
Поэтому toString() должен быть вызван на экземпляр.
Итак, почему null.toString() работает потрясающе? Sysout заботится об этом?
EDIT: На самом деле я увидел эту странную вещь с append() StringBuilder. Так что попробовал с Sysout. Оба ведут себя одинаково. Так и этот метод заботится?
Ответы
Ответ 1
PrintWriter
println(Object)
(это метод, вызываемый при записи System.out.println(nothingToHold)
), вызывает String.valueOf(x)
, как описано в Javadoc:
/**
* Prints an Object and then terminates the line. This method calls
* at first String.valueOf(x) to get the printed object string value,
* then behaves as
* though it invokes <code>{@link #print(String)}</code> and then
* <code>{@link #println()}</code>.
*
* @param x The <code>Object</code> to be printed.
*/
public void println(Object x)
String.valueOf(Object)
преобразует значение null в значение "null":
/**
* Returns the string representation of the <code>Object</code> argument.
*
* @param obj an <code>Object</code>.
* @return if the argument is <code>null</code>, then a string equal to
* <code>"null"</code>; otherwise, the value of
* <code>obj.toString()</code> is returned.
* @see java.lang.Object#toString()
*/
public static String valueOf(Object obj)
Ответ 2
Метод PrintStream#println(Object s)
вызывает PrintStream#print(String s)
, который сначала проверяет, является ли аргумент null
, и если он есть, то просто устанавливает "null"
для печати как простой String
.
Однако то, что передается методу .print()
, равно "null"
как String
, потому что String.valueOf(String s)
возвращает "null"
перед вызовом метода .print()
.
public void print(String s) {
if (s == null) {
s = "null";
}
write(s);
}
Ответ 3
Вот документация для println()
Распечатывает строку, за которой следует новая строка. Строка преобразуется в массив байтов с использованием кодировки, выбранной при построении этот поток. Затем байты записываются в целевой поток с помощью писать (INT).
Если возникает ошибка ввода-вывода, в этом состоянии ошибки потока установлено значение true.
NULL
может преобразовывать в байты.
Ответ 4
Object nothingToHold = null;
System.out.println(nothingToHold != null ? nothingToHold : "null String or any thing else");
Это будет отображать вывод, если NothingToHold (Object) не равно null, иначе оно печатает сообщение как "null String или что-то еще"
Ответ 5
Код говорит громче, чем слова.
class PrintStream {
public void println(Object x) {
String s = String.valueOf(x);
// ...
}
}
class String {
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
}