带有null参数的Java方法调度

为什么我(显然)会直接传递null作为参数,或者传递一个我赋值为nullObject

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

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

我确信为什么foo(testVal)会转到foo(Object)

foo(null)转到foo(String)的原因有点复杂。 常量null的类型为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)"); } } 

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

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

用1.6.0 foo(null)调度到最适用的方法foo(String)…

如果添加新方法说foo(整数),则编译器无法选择最具体的适用方法并显示错误。

-Patrick

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

@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)"); } }