根据文档,方法String.valueOf(Object obj)
返回:
如果参数为
null
,则字符串等于"null"
;否则,返回obj.toString()
的值。
但是当我尝试这样做时:
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中的一个主要错误吗?
答案 0 :(得分:190)
问题是String.valueOf
方法重载:
Java规范语言要求在这种情况下,选择最具体的重载:
如果多个成员方法都可访问并适用于方法调用,则必须选择一个为运行时方法调度提供描述符。 Java编程语言使用选择最具体方法的规则。
char[]
是 Object
,但并非所有Object
都是 char[]
。因此,char[]
更具体而不是Object
,并且根据Java语言的规定,在这种情况下会选择String.valueOf(char[])
重载。
String.valueOf(char[])
期望数组不是null
,并且在这种情况下给出了null
,然后它会抛出NullPointerException
。
简单的“修复”是将null
明确地转换为Object
,如下所示:
System.out.println(String.valueOf((Object) null));
// prints "null"
有几个重要的:
valueOf(char[])
重载!null
(示例)null
至少有两种情况需要明确地将null
强制转换为特定的引用类型:
null
作为vararg参数的单个参数后者的一个简单示例如下:
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"
答案 1 :(得分:16)
问题是您正在呼叫String.valueOf(char[])
而不是 String.valueOf(Object)
。
原因是Java将始终选择与提供的参数一起使用的重载方法的最具体版本。 null
是Object
参数的有效值,但它也是char[]
参数的有效值。
要使Java使用Object
版本,请通过变量传递null
或指定显式强制转换为Object:
Object o = null;
System.out.println("String.valueOf(null) = " + String.valueOf(o));
// or
System.out.println("String.valueOf(null) = " + String.valueOf((Object) null));
答案 2 :(得分:5)
2003年以这种方式提交了一个编号为4867608的错误,该解释为“无法修复”此解释。
由于兼容性限制,我们无法更改此设置。请注意它是 最终的public static String valueOf(char data [])方法 被调用,它没有提到替换“null” null arguments。
@ ###。### 2003-05-23
答案 3 :(得分:0)
在Scala中使用String.valueOf(null: Any)
。