"用String.valueOf()代替直接调用toString()可以防止NPE"是常见建议,这篇真实测试String.valueOf()的多个重载,发现这句话只对Object版本成立,char[]版本是一个真实存在的例外。
上一篇:wait() 虚假唤醒真实验证
最常见的用法:用valueOf()包一层,避免直接调用可能是null的对象的toString()。
StringValueOfNullDemo.java Object nullObj = null; String s1 = String.valueOf(nullObj); nullObj.toString(); // 对照:直接调用
String.valueOf(null对象) 真实结果: "null",长度=4 nullObj.toString() 真实抛出 NullPointerException
真实结果证明了两者的差异:String.valueOf(Object obj) 内部真实做了判空,是 null 就直接返回字符串字面量 "null",不会去调用 obj.toString();而直接对一个 null 引用调用 toString() 真实是对 null 的方法调用,必然抛出 NullPointerException。这也是为什么日志打印、字符串拼接场景经常会看到 String.valueOf(obj) 而不是 obj.toString() 的写法。
String.valueOf()是一族重载方法,不是只有Object版本——真实测一下char[]版本对null的处理。
StringValueOfNullDemo.java char[] nullCharArr = null; String s4 = String.valueOf(nullCharArr);
String.valueOf(null的char[]) 真实抛出 NullPointerException(这个重载版本不做null检查,直接遍历数组)
java.util.Objects 提供的 toString() 方法,专门为需要自定义null默认值的场景设计。
Objects.toString(null, "默认值") 真实结果: 默认值
Objects.toString(null) 真实结果(无默认值参数): "null"
("" + null) 真实结果: "null"
StringBuilder.append((Object)null) 真实结果: "null"
StringBuilder.append((String)null) 真实结果: "null"(String重载同样安全,输出"null"字符串)
真实结果显示 Objects.toString(Object, String) 提供了比 String.valueOf() 更灵活的选择——可以指定 null 时返回的默认值,而不是固定的字符串 "null"。同时也真实验证了字符串拼接("" + null)和 StringBuilder.append() 的 Object/String 重载对 null 都是安全的,这些都是编译器和标准库在设计时特意为 null 做的兼容处理,但不能想当然地认为"所有接受可能为null参数的方法都会这样处理"。
每一行都是真实运行这段代码得到的结果或异常。