具有空参数的 Java 方法调度

2022-09-04 07:18:22

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

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的第二个答案中的评论。谢谢大家的帮助。


答案 1

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

我相信很明显为什么去.foo(testVal)foo(Object)

去的原因有点复杂。常量的类型是 ,它是所有类型的子类型。因此,这扩展了 ,它扩展了 。foo(null)foo(String)nullnulltypenulltypeStringObject

调用编译器时,请查找具有最特定类型的重载方法。因为它更具体,那么这就是被调用的方法。foo(null)StringObject

如果你有另一个像 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)");
  }

}

答案 2

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