为什么我(显然)会直接将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的第二个答案中的评论。)感谢大家的帮助。
答案 0 :(得分:24)
您使用的是哪个版本的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)");
}
}
答案 1 :(得分:2)
因为第二个带有null的注释掉调用对编译器来说是不明确的。文字null可以是字符串或对象。而指定的值具有明确的类型。你需要转换null,例如test.foo((String)null)消除歧义。
答案 2 :(得分:1)
有没有人试过这个例子???
用1.6.0 foo(null)调度到最适用的方法foo(String)...
如果你添加一个新方法说foo(整数),编译器就无法选择最具体的适用方法并显示错误。
-Patrick
答案 3 :(得分: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)");
}
}