2008-12-18 59 views
12

为什么它(显然)有所作为是否我直接传递null作为参数,或者传递一个Object,我分配null与null参数的Java方法分派

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

回答

24

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

我相信它明显的原因foo(testVal)foo(Object)

foo(null)转到foo(String)的原因有点复杂。常数null的类型为nulltype,它是所有类型的子类型。所以,这nulltype延伸String,延伸Object

当您致电foo(null)编译器查找最具体类型的重载方法。由于String更具体,因此Object即被调用的方法。

如果你有另一个与字符串一样特定的过载,比如说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)"); 
    } 

} 
+0

刚刚测试这一点,我目瞪口呆的是,(一)6u11不说这是不明确的,和(b)在空解析字符串不会反对。每天学习新东西 - +1课程。 – 2008-12-18 09:17:32

+1

@Software Monkey:一旦您接受常量null为null类型,并且null类型为所有类型的子类型,这是非常明显的。 Object 2008-12-18 10:16:39

2

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

1

有没有人试过这个例子?

随着1.6.0富(空)被分派到适用的最具体的方法是FOO(字符串)...

如果添加了新的方法说FOO(整数)编译器不能选择最具体适用的方法并显示错误。

-Patrick

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