Java String.valueOf(null)抛出NPE,但Object a = null; String.valueOf(a)返回'null'

是否存在对以下行为的逻辑语言devisetypes解释(Java 7和我怀疑以前的版本):

Object a = null; String as = String.valueOf(a); // as is assigned "null" System.out.println(as+":"+as.length()); // prints: "null:4" System.out.println ( String.valueOf(null)); // NPE 

在语句System.out.println(String.valueOf(null)); 有一个方法public static String valueOf(char data[])的调用,其源代码如下:

 public static String valueOf(char data[]) { return new String(data); } 

这就是为什么你得到NPE

另一方面,在语句Object a = null; String as = String.valueOf(a); Object a = null; String as = String.valueOf(a); 有一个方法public static String valueOf(Object obj)的调用,其源代码如下:

 public static String valueOf(Object obj) { return (obj == null) ? "null" : obj.toString(); } 

这就是为什么你得到“空”,而不是NPE


Java语言规范的一些理论: 15.12.2.5select最具体的方法

如果多个成员方法都可以访问并适用于方法调用,则需要select一个方法来为运行时方法调度提供描述符。 Java编程语言使用最具体的方法select的规则。

char[]Objecttypes的,但不是所有的Object都是char[]types的。 typeschar[]比Object 更具体 ,并且如Java Language Specification中所述,在这种情况下,将selectString.valueOf(char[])重载。

编辑

还值得一提的是伊恩·罗伯茨 ( Ian Roberts )在他的评论中提到的:

重要的是要注意,如果没有比所有其他重要更重要的单一重载 – 如果存在valueOf(String)方法以及valueOf(Object)valueOf(char[])那么这是一个编译错误,那么调用到无types的String.valueOf(null)将是不明确的

第一个调用是String#valueOf(Object) ,第二个是String#valueOf(char[])

重载方法是根据参数的静态types来select的,这就是为什么第一个工作和第二个获得NPE的原因。

如果你调用System.out.println ( String.valueOf((Object)null)); 它会工作

这是因为在String类中的这个代码:

 public static String valueOf(char data[]) { return new String(data); } 

你的代码(抛出NullPointerException )调用上面提到的方法,因此data字段为null 。 实际上,这个调用是由构造函数中的String类抛出的。

使用JDK 6,exception如下所示:

 java.lang.NullPointerException at java.lang.String.<init>(String.java:177) at java.lang.String.valueOf(String.java:2840) at org.bfs.data.SQLTexter.main(SQLTexter.java:364) 

至于你的路线:

 System.out.println(as+":"+as.length()); // prints: "null:4" 

这个工作方式如下所示:

 public static String valueOf(Object obj) { return (obj == null) ? "null" : obj.toString(); } 

显然, aObjecttypes的,所以String.valueOf(Object)方法被调用。

如果您特别想调用String.valueOf(Object obj)方法,请按如下方式对您的null进行types转换:

 System.out.println (String.valueOf((Object)null)); 

您遇到方法重载(其中有几个方法具有相同的名称和方法签名,但具有不同的方法参数)。 在你的情况下(NPE发生的地方),JVM根据最具体的静态types决定调用哪个方法。 如果声明了types,那么最具体的方法是声明variables的参数types相同的方法,否则,JVM使用最具体的方法规则来查找要调用的方法。

我希望这有帮助。