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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3131865/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 16:43:08  来源:igfitidea点击:

Why does String.valueOf(null) throw a NullPointerException?

javanullnullpointerexceptionoverloadingapi-design

提问by user282886

according to the documentation, the method String.valueOf(Object obj)returns:

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

if the argument is null, then a string equal to "null"; otherwise, the value of obj.toString()is returned.

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

But how come when I try do this:

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

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

it throws NPE instead? (try it yourself if you don't believe!)

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

    Exception in thread "main" java.lang.NullPointerException
    at java.lang.String.(Unknown Source)
    at java.lang.String.valueOf(Unknown Source)

How come this is happening? Is the documentation lying to me? Is this a major bug in Java?

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

采纳答案by polygenelubricants

The issue is that String.valueOfmethod is overloaded:

问题是该String.valueOf方法已重载

Java Specification Language mandates that in these kind of cases, the most specific overloadis chosen:

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

JLS 15.12.2.5 Choosing the Most Specific Method

JLS 15.12.2.5 选择最具体的方法

If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specificmethod is chosen.

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

A char[]is-anObject, but not all Objectis-achar[]. Therefore, char[]is more specificthan Object, and as specified by the Java language, the String.valueOf(char[])overload is chosen in this case.

A char[]is-anObject,但并非所有Objectis-achar[]。因此,char[]更具体的Object,和由Java语言指定,String.valueOf(char[])超载被选择在这种情况下。

String.valueOf(char[])expects the array to be non-null, and since nullis given in this case, it then throws NullPointerException.

String.valueOf(char[])期望数组为 non- null,并且由于null在这种情况下给出,因此它抛出NullPointerException

The easy "fix" is to cast the nullexplicitly to Objectas follows:

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

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

Related questions

相关问题



Moral of the story

故事的道德启示

There are several important ones:

有几个重要的:

  • Effective Java 2nd Edition, Item 41: Use overloading judiciously
    • Just because you can overload, doesn't mean you should every time
    • They can cause confusion (especially if the methods do wildly different things)
  • Using good IDE, you can check which overload is selected at compile time
    • With Eclipse, you can mouse-hover on the above expression and see that indeed, the valueOf(char[])overload is selected!
  • Sometimes you want to explicitly cast null(examples to follow)
  • Effective Java 2nd Edition,Item 41:明智地使用重载
    • 仅仅因为你可以超载,并不意味着你每次都应该
    • 它们会引起混乱(尤其是如果这些方法做的事情大不相同)
  • 使用好的IDE,可以检查编译时选择了哪个重载
    • 使用 Eclipse,您可以将鼠标悬停在上述表达式上,并看到确实valueOf(char[])选择了重载!
  • 有时您想显式转换null(要遵循的示例)

See also

也可以看看



On casting null

铸造时 null

There are at least two situations where explicitly casting nullto a specific reference type is necessary:

至少有两种情况需要显式转换null为特定的引用类型:

  • To select overloading (as given in above example)
  • To give nullas a single argument to a vararg parameter
  • 选择重载(如上例所示)
  • 为了给null作为单个参数的可变参数参数

A simple example of the latter is the following:

后者的一个简单示例如下:

static void vararg(Object... os) {
    System.out.println(os.length);
}

Then, we can have the following:

然后,我们可以有以下内容:

vararg(null, null, null); // prints "3"
vararg(null, null);       // prints "2"
vararg(null);             // throws NullPointerException!

vararg((Object) null);    // prints "1"

See also

也可以看看

Related questions

相关问题

回答by Joachim Sauer

The problem is that you're calling String.valueOf(char[])and notString.valueOf(Object).

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

The reason for this is that Java will always choose the most specific version of an overloaded method that works with the provided parameters. nullis a valid value for an Objectparameter, but it's also a valid value for a char[]parameter.

这样做的原因是 Java 将始终选择使用提供的参数的重载方法的最具体版本。nullObject参数的有效值,但它也是char[]参数的有效值。

To make Java use the Objectversion, either pass in nullvia a variable or specify an explicit cast to Object:

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

回答by cbare

A bug, numbered 4867608was filed for this way back in 2003, which was resolved as "won't fix" with this explanation.

早在 2003 年,就以这种方式提交了编号为4867608的错误,并在此解释下将其解决为“无法修复”。

We can't change this due to compatibility constraints. Note that it is the public static String valueOf(char data[]) method which ends up being invoked and it does not mention the replacement of "null" for null arguments.

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

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

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