Java中“(Object)null”和“null”有什么区别?

时间:2013-10-11 11:30:09

标签: java null nullpointerexception

看看下面的例子:

class nul
{
  public static void main (String[] args)
  {
    System.out.println (String.valueOf((Object)null));
    System.out.println (String.valueOf(null));
  }
}

第一个printlnnull,但第二个NullPointerException。{/ p>

为什么只有第二行值得例外?这两个null之间有什么区别? Java中是否有真正的 null null

3 个答案:

答案 0 :(得分:56)

第一次调用将调用String.valueOf(Object)方法,因为您明确地将null标记为Object引用。相反,第二个方法将调用重载的String.valueOf(char[])方法,因为char[]对于Object参数比null更具体。

此方法的其他重载版本接受原始参数,但这些参数不是null参数的有效匹配。

来自JLS §15.12.2

  

可能有多种这样的方法,在这种情况下最多   选择特定的一个。描述符(签名加返回类型)   最具体的方法是在运行时使用该方法来执行该方法   调度。

     

如果方法适用于子类型,则该方法适用   (§15.12.2.2),适用于方法调用转换(§15.12.2.3),   或者它是适用的变量arity方法(§15.12.2.4)。

     

[...]

     

如果在其中一个方法中确定了几种适用的方法   适用性测试的三个阶段,然后是最具体的一个阶段   选择,如第15.12.2.5节所述。

现在检查两种方法的源代码:

// This won't throw NPE for `obj == null`
public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

// This will throw `NPE` for `data == null`
public static String valueOf(char data[]) {
    return new String(data);
}

答案 1 :(得分:16)

Java中有许多重载的String.valueOf方法。此外,在Java null中有任何和所有类型,以便任何(不是原始的)可以是null

因此,当您致电(String.valueOf((Object)null)时,您调用valueOf方法,该方法将Object用作null显式转换为Object

在第二个示例中,您没有明确地将null强制转换为任何特定类型,因此实际上您使用valueOf调用char[]方法会抛出NPE。

来自JLS §15.12.2

  

第二步搜索上一步中确定的类型   成员方法。此步骤使用方法的名称和类型   用于查找可访问的方法的参数表达式   适用的,即可以正确调用的声明   给定的论点。

     

可能有多种这样的方法,在这种情况下最多   选择特定的一个。描述符(签名加返回类型)   最具体的方法是在运行时使用该方法来执行该方法   调度。

在这种情况下,char[] 更具体而不是Object,因此在没有明确演员null时会调用它。

答案 2 :(得分:6)

虽然我已经接受了一个答案,但我想补充问题的确切答案,因为这两个答案集中在解释我走进的陷阱。

(Object)nullnull之间的区别在于第一个的类型被强制为Object,但第二个的类型不是,正如人们所能想到的那样,被迫Object 1}}。相反,它也可以是一个数组而不是一个对象。

所以结论是:将(Object)null而不是null作为参数传递给方法,以确保完全获取处理对象的方法而不是任何其他处理数组的方法。