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

2022-09-01 05:54:02

对于以下行为,是否有逻辑语言设计类型的解释(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

答案 1

在语句中有一个调用方法,其源代码如下: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);public static String valueOf(Object obj)

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

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


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

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

A 是类型,但不是所有类型都是 类型。类型比对象更具体,如 Java 语言规范中所述,在这种情况下选择重载。char[]ObjectObjectchar[]char[]String.valueOf(char[])

编辑

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

重要的是要注意,如果没有比所有其他重载更具体的单个重载,则这是一个编译错误 - 如果有一个方法以及,那么对非类型化的调用将是模棱两可的valueOf(String)valueOf(Object)valueOf(char[])String.valueOf(null)


答案 2

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

重载方法是根据参数的静态类型选择的,这就是为什么第一个有效,秒获得NPE的原因。

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