根据文档,方法 String.valueOf(Object obj)
返回:
if the argument is
null
, then a string equal to"null"
; otherwise, the value ofobj.toString()
is returned.
但是当我尝试这样做时怎么会:
System.out.println("String.valueOf(null) = " + String.valueOf(null));
它会抛出 NPE 吗? (不信你自己试试!)
Exception in thread "main" java.lang.NullPointerException at java.lang.String.(Unknown Source) at java.lang.String.valueOf(Unknown Source)
这是怎么回事?文件是在骗我吗?这是 Java 的主要错误吗?
最佳答案
问题是 String.valueOf
方法被重载:
Java 规范语言要求在这些情况下,选择最具体的重载:
JLS 15.12.2.5 Choosing the Most Specific Method
If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen.
一个char[]
is-an Object
,但不是所有Object
is-a char[]
。因此,char[]
比 Object
更具体,并且按照 Java 语言的规定,String.valueOf(char[ ])
在这种情况下选择重载。
String.valueOf(char[])
期望数组是非null
,并且由于在这种情况下给出了null
,然后它抛出 NullPointerException
。
简单的“修复”是将 null
显式转换为 Object
,如下所示:
System.out.println(String.valueOf((Object) null));
// prints "null"
相关问题
故事的寓意
有几个重要的:
- Effective Java 第 2 版,第 41 条:明智地使用重载
- 仅仅因为你可以重载,并不意味着你每次都应该这样做
- 它们可能会引起困惑(尤其是当方法做的事情完全不同时)
- 使用好的IDE,可以在编译时检查选择了哪个重载
- 在 Eclipse 中,您可以将鼠标悬停在上述表达式上并看到 确实,选择了
valueOf(char[])
重载!
- 在 Eclipse 中,您可以将鼠标悬停在上述表达式上并看到 确实,选择了
- 有时你想显式地强制转换
null
(后面的例子)
另见
关于转换 null
至少有两种情况需要将 null
显式转换为特定的引用类型:
- 选择重载(如上例所示)
- 将
null
作为单个参数提供给可变参数
后者的一个简单例子如下:
static void vararg(Object... os) {
System.out.println(os.length);
}
然后,我们可以有以下内容:
vararg(null, null, null); // prints "3"
vararg(null, null); // prints "2"
vararg(null); // throws NullPointerException!
vararg((Object) null); // prints "1"
另见
- Java Language Guide/varargs - 了解它是如何实现的
相关问题
关于java - 为什么 String.valueOf(null) 会抛出 NullPointerException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3131865/