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

问题描述 投票:0回答:4

根据文档,方法

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 中的一个重大错误吗?

java null nullpointerexception overloading api-design
4个回答
216
投票

问题是

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[])

期望数组为非

null
,并且由于在这种情况下给出了
null
,因此它会抛出
NullPointerException

简单的“修复”是将

null

显式转换为

Object
,如下所示:

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

相关问题

    多态歧义区分是如何工作的?
  • Java 中哪个重载会被选择为 null?
故事的寓意

有几个重要的:

    Effective Java 第二版,第 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"

另请参阅

    Java 语言指南/varargs
  • - 了解它是如何实现的
  • 相关问题

    为什么要空转换?
  • 形参类型声明中double…和double[]的区别

19
投票

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));



5
投票
4867608

的错误,并通过此解释将其解决为“无法修复”。

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

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


-1
投票
String.valueOf(null: Any)

,否则推断

String.valueOf(null: Array[Char])
。同样,在 java 中,如果您对隐式转换不满意,则需要显式转换。在 IntelliJ 中,在使用 valueOf 时按 Ctrl+B 将使您在可以使用的众多 valueOf 版本中找到您使用的 valueOf 版本。
    

© www.soinside.com 2019 - 2024. All rights reserved.