13

为什么(显然)我null是直接作为参数传递,还是传递Object我分配的 null

Object testVal = null;
test.foo(testVal);    // dispatched to foo(Object)
// test.foo(null);    // compilation problem -> "The method foo(String) is ambiguous"   

public void foo(String arg) { // More-specific
    System.out.println("foo(String)");
}

public void foo(Object arg) { // Generic
    System.out.println("foo(Object)");
}

换句话说,为什么(注释掉的)第二个调用foo(...)未发送到foo(Object)

更新:我使用 Java 1.6。我可以毫无问题地编译 Hemal 的代码,但我的仍然无法编译。我看到的唯一区别是 Hemal 的方法是静态的,而我的不是。但我真的不明白为什么这会有所作为......?

更新 2:已解决。我的班级中有另一个方法 foo(Runnable),因此调度程序无法明确选择单个最具体的方法。(请参阅我在 Hemal 的第二个答案中的评论。)感谢大家的帮助。

4

4 回答 4

24

您使用的是哪个版本的 Java?使用 1.6.0_11 代码(粘贴在下面)编译并运行。

我敢肯定,为什么foo(testVal)要去foo(Object)

foo(null)去的原因foo(String)有点复杂。常量null是 type nulltype,它是所有类型的子类型。所以,这nulltype延伸String了,延伸了Object

当您调用foo(null)编译器时,会查找具有最特定类型的重载方法。因为String更具体,所以Object这是被调用的方法。

如果您有另一个与 String 一样具体的重载,foo(Integer)那么您会得到一个模棱两可的重载错误。

class NullType {

  public static final void main(final String[] args) {
    foo();
  }

  static void foo()
  {
    Object testVal = null;
    foo(testVal);    // dispatched to foo(Object)
    foo(null);    // compilation problem -> "The method foo(String) is ambiguous"   
  }

  public static void foo(String arg) { // More-specific
    System.out.println("foo(String)");
  }

  public static void foo(Object arg) { // Generic
    System.out.println("foo(Object)");
  }

}
于 2008-12-18T08:45:18.270 回答
2

因为第二个用 null 注释掉的调用对编译器来说是模棱两可的。文字 null 可以是字符串或对象。而分配的值具有确定的类型。您需要强制转换为空值,例如 test.foo((String)null) 以消除歧义。

于 2008-12-18T08:35:17.680 回答
1

有没有人试过这个例子???

在 1.6.0 中,foo(null) 被分派到最具体的适用方法,即 foo(String)...

如果您添加一个新方法,比如 foo(Integer),编译器将无法选择最具体的适用方法并显示错误。

-帕特里克

于 2008-12-18T08:46:49.857 回答
1

很抱歉使用答案来发表评论,但我需要发布不适合评论的代码。

@Yang,我也可以编译和运行以下内容。你能发布一个完整的代码,用一行注释编译,这样如果我取消注释那一行,它就不会编译?

class NullType {

  public static final void main(final String[] args) {
    foo();
    new Test().bar(new Test());
  }

  static void foo()
  {
    Object testVal = null;
    foo(testVal);    // dispatched to foo(Object)
    // foo(null);    // compilation problem -> "The method foo(String) is ambiguous"   
  }

  public static void foo(String arg) { // More-specific
    System.out.println("foo(String)");
  }

  public static void foo(Integer arg) { // More-specific
    System.out.println("foo(Integer)");
  }

  public static void foo(Object arg) { // Generic
    System.out.println("foo(Object)");
  }


}


class Test
{
  void bar(Test test)
  {
    Object testVal = null;
    test.foo(testVal);    // dispatched to foo(Object)
    test.foo(null);    // compilation problem -> "The method foo(String) is ambiguous"   
  }

  public void foo(String arg) { // More-specific
    System.out.println("foo(String)");
  }

  public void foo(Object arg) { // Generic
    System.out.println("foo(Object)");
  }
}
于 2008-12-18T10:22:49.540 回答