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

时间:2010-06-28 11:18:51

标签: java null nullpointerexception overloading api-design

根据文档,方法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中的一个主要错误吗?

4 个答案:

答案 0 :(得分:190)

问题是String.valueOf方法重载

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

JLS 15.12.2.5 Choosing the Most Specific Method

  

如果多个成员方法都可访问并适用于方法调用,则必须选择一个为运行时方法调度提供描述符。 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"

相关问题


故事的道德

有几个重要的:

  • Effective Java 2nd Edition,Item 41:明智地使用重载
    • 仅仅因为你可以超负荷,并不意味着每次都应该
    • 它们可能引起混淆(特别是如果方法做了截然不同的事情)
  • 使用好的IDE,您可以检查在编译时选择了哪个重载
    • 使用Eclipse,您可以鼠标悬停在上面的表达式上,看到确实,选择了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将始终选择与提供的参数一起使用的重载方法的最具体版本。 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));

答案 2 :(得分:5)

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

  

由于兼容性限制,我们无法更改此设置。请注意它是   最终的public static String valueOf(char data [])方法   被调用,它没有提到替换“null”   null arguments。

     

@ ###。### 2003-05-23

答案 3 :(得分:0)

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