为什么 String.valueOf(null) 抛出 NullPointerException?

新手上路,请多包涵

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

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

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

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

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

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

为什么会这样?文档是在骗我吗?这是 Java 中的主要错误吗?

原文由 user282886 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 893
2 个回答

问题是 String.valueOf 方法 _重载_:

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

JLS 15.12.2.5 选择最具体的方法

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

A char[] is-an Object , but not all Object is-a char[] .因此, char[]Object _更具体_,并且根据 Java 语言的规定,在这种情况下选择了 String.valueOf(char[]) 重载。

String.valueOf(char[]) expects the array to be non- null , and since null is given in this case, it then throws 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"

也可以看看

相关问题

原文由 polygenelubricants 发布,翻译遵循 CC BY-SA 3.0 许可协议

问题是您正在调用 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));

原文由 Joachim Sauer 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题