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[]
是Object
types的,但不是所有的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(); }
显然, a
是Object
types的,所以String.valueOf(Object)
方法被调用。
如果您特别想调用String.valueOf(Object obj)
方法,请按如下方式对您的null进行types转换:
System.out.println (String.valueOf((Object)null));
您遇到方法重载(其中有几个方法具有相同的名称和方法签名,但具有不同的方法参数)。 在你的情况下(NPE发生的地方),JVM根据最具体的静态types决定调用哪个方法。 如果声明了types,那么最具体的方法是声明variables的参数types相同的方法,否则,JVM使用最具体的方法规则来查找要调用的方法。
我希望这有帮助。