【问题标题】:What is the difference between "(Object)null" and "null" in Java? [duplicate]Java中的“(Object)null”和“null”有什么区别? [复制]
【发布时间】:2013-10-19 11:18:51
【问题描述】:

看看下面的例子:

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

第一个println 写入null,但第二个抛出NullPointerException

为什么只有第二行值得例外?而这两个nulls 有什么区别呢?在 Java 中是否有 real nullfake null

【问题讨论】:

标签: java null nullpointerexception


【解决方案1】:

第一次调用将调用String.valueOf(Object) 方法,因为您已将null 显式类型转换为Object 引用。相反,第二个将调用重载的String.valueOf(char[]) 方法,因为char[] 对于null 参数比Object 更具体。

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

来自JLS §15.12.2

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

一个方法是适用的,如果它可以通过子类型应用 (§15.12.2.2),适用于方法调用转换(§15.12.2.3), 或者它是一种适用的可变数量方法(§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);
}

【讨论】:

  • (因为编译器将使用null 作为参数调用的方法解析为它所能找到的最具体的参数。并且char[]Object 更具体。)
  • 所以这是一个Java错误,因为valueOf的两个实现不做同样的事情。 Object 实现认为 null 应该打印为 null,但 char 数组实现认为 null 应该导致异常。相同的方法对异常有不同的看法。
  • @ceving java 错误?不,绝对不是! Object 应该打印为null。并且 null char[] 无法转换为 String 因此引发异常。它们是不同的方法,这就是重点。错误到底在哪里?
  • @htor . 用于static 方法,# 用于instance 方法。嗯,不,没有任何标准。
  • @BoristheSpider 如果他们有不同的名字,我会同意你的看法。但它们具有相同的名称,因此不是不同的方法。
【解决方案2】:

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

因此,当您调用(String.valueOf((Object)null) 时,您调用了valueOf 方法,该方法采用Object 作为使用明确地将null 转换为Object

在第二个示例中,您没有将null 显式转换为任何特定类型,因此实际上您使用char[] 调用valueOf 方法会引发NPE。

来自JLS §15.12.2

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

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

在这种情况下,char[]Object更具体,因此在没有明确转换null 时调用它。

【讨论】:

  • 因此底线是避免将原始null 作为参数传递给方法,而不是将它们转换为该方法的参数类型。 :)
【解决方案3】:

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

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

因此结论是:将 (Object)null 而不是 null 作为参数传递给方法,以确保准确地获得适用于对象的方法,而不是适用于数组的任何其他方法。

【讨论】:

  • 嗯,是的,正如 Rohit 已经提到的,方法调用将始终与具有最具体子类型的方法匹配。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-23
  • 2012-11-14
  • 1970-01-01
  • 2015-07-19
  • 2018-03-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多