132

根据文档,该方法String.valueOf(Object obj)返回:

如果参数是null,则字符串等于"null"; 否则,obj.toString()返回 的值。

但是当我尝试这样做时怎么会:

System.out.println("String.valueOf(null) = " + String.valueOf(null));

它会抛出 NPE 吗?(不信你自己试试!)

    线程“主”java.lang.NullPointerException 中的异常
    在 java.lang.String.(Unknown Source)
    在 java.lang.String.valueOf(未知来源)

怎么会这样?文件是在骗我吗?这是Java中的主要错误吗?

4

4 回答 4

210

问题是String.valueOf方法重载

Java 规范语言要求在这些情况下,选择最具体的重载

JLS 15.12.2.5 选择最具体的方法

如果多个成员方法既可访问又适用于方法调用,则有必要选择一个为运行时方法分派提供描述符。Java 编程语言使用选择最具体方法的规则。

A char[] is-an Object,但并非所有Object is-a char[]。因此,char[]比更具体Object,并且按照 Java 语言的规定,String.valueOf(char[])在这种情况下选择重载。

String.valueOf(char[])期望数组是 non- null,并且因为null在这种情况下给出了,所以它会抛出NullPointerException.

简单的“修复”是将null显式转换Object为如下:

System.out.println(String.valueOf((Object) null));
// prints "null"

相关问题


故事的道德启示

有几个重要的:

  • Effective Java 第 2 版,第 41 条:明智地使用重载
    • 仅仅因为你可以超载,并不意味着你每次都应该
    • 它们可能会引起混乱(特别是如果方法做的事情完全不同)
  • 使用好的IDE,你可以在编译时检查选择了哪个重载
    • 使用 Eclipse,您可以将鼠标悬停在上面的表达式上,并看到确实选择了valueOf(char[])重载!
  • 有时你想显式地强制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"

也可以看看

相关问题

于 2010-06-28T11:21:22.537 回答
18

问题是您正在打电话String.valueOf(char[])不是 String.valueOf(Object).

这样做的原因是 Java 将始终选择与提供的参数一起使用的重载方法的最具体版本。nullObject参数的有效值,但它也是参数的有效值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));
于 2010-06-28T11:26:52.367 回答
4

早在 2003 年就以这种方式提交了一个编号为4867608的错误,该错误已通过此解释解决为“无法修复”。

由于兼容性限制,我们无法更改此设置。请注意,最终调用的是公共静态 String valueOf(char data[]) 方法,并且它没有提到将“null”替换为 null 参数。

@###.### 2003-05-23

于 2012-11-01T18:56:15.527 回答
0

String.valueOf(null: Any)在 Scala 中使用。

于 2020-07-01T15:20:34.767 回答