为什么对象实例(为空)上的 toString() 不抛出 NPE?

2022-09-03 12:23:37

考虑以下一个:

Object nothingToHold = null;

System.out.println(nothingToHold);  //  Safely prints 'null'

在这里,Sysout 一定是在期待 String。所以 toString() 必须在实例上被调用。

那么为什么null.toString()工作得很棒呢?Sysout 是否在处理此事?

编辑:实际上我看到了StringBuilder的append()这个奇怪的事情。所以尝试了Sysout。两者的行为方式相同。那么这种方法也要小心吗?


答案 1

PrintWriter的 s(这是编写时调用的方法)调用,如 Javadoc 中所述:println(Object)System.out.println(nothingToHold)String.valueOf(x)

/**
 * Prints an Object and then terminates the line.  This method calls
 * at first String.valueOf(x) to get the printed object's 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

但是,传递给该方法的内容是 as ,因为返回是在被调用的方法之前返回的。.print()"null"StringString.valueOf(String s)"null".print()

public void print(String s) {
    if (s == null) {
        s = "null";
    }
    write(s);
}

推荐