带 null 参数的 Java 方法调度
为什么(显然)无论我直接传递 null
作为参数,还是传递我分配了值的Object
,都会产生影响空?
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 的第二个答案中的评论。)感谢大家的帮助。
Why does it (apparently) make a difference whether I pass null
as an argument directly, or pass an Object
that I assigned the value 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)");
}
In other words, why is the (commented-out) second call to foo(...)
not dispatched to foo(Object)
?
Update: I use Java 1.6. I could compile Hemal's code without problems, but mine still doesn't compile. The only difference I see is that Hemal's methods are static while mine are not. But I really don't see why this should make a difference...?
Update 2: Solved. I had another method foo(Runnable) in my class, so the dispatcher couldn't unambiguously select the single most specific method. (See my comment in Hemal's second answer.) Thanks everyone for your help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
有人试过这个例子吗???
在 1.6.0 中,foo(null) 被分派到最具体的适用方法,即 foo(String)...
如果添加新方法,如 foo(Integer),编译器将无法选择最具体的适用方法并显示错误。
-帕特里克
Has anyone tried the example ???
With 1.6.0 foo(null) is dispatched to the most specific method applicable which is foo(String)...
If you add a new method say foo(Integer) the compiler cannot choose the most specific applicable method and shows an error.
-Patrick
很抱歉使用答案来发表评论,但我需要发布不适合评论的代码。
@Yang,我还可以编译并运行以下内容。 您能否发布一个完整的代码,该代码可以用注释行进行编译,这样如果我取消注释该行,它就不会编译?
Sorry to use an answer, for a comment, but I need to post code that won't fit in comment.
@Yang, I am also able to compile and run the following. Can you post a complete code that compiles with one line commented such that if I uncomment that line it won't compile?
您使用的是哪个版本的 Java? 在 1.6.0_11 中,代码(粘贴在下面)可以编译并运行。
我确信为什么
foo(testVal)
转到foo(Object)
是显而易见的。foo(null)
转到foo(String)
的原因有点复杂。 常量null
的类型为nulltype
,它是所有类型的子类型。 因此,这个nulltype
扩展了String
,而String
扩展了Object
。当您调用 foo(null) 时,编译器会查找具有最特定类型的重载方法。 由于
String
比Object
更具体,因此它是被调用的方法。如果您有另一个与 String 一样具体的重载,例如
foo(Integer)
那么您将得到一个不明确的重载错误。Which version of Java are you using? With 1.6.0_11 the code (pasted below) compiles and runs.
I am sure its obvious why
foo(testVal)
goes tofoo(Object)
.The reason why
foo(null)
goes tofoo(String)
is a little complex. The constantnull
is of typenulltype
, which is a subtype of all types. So, thisnulltype
extendsString
, which extendsObject
.When you call
foo(null)
compiler looks for the overloaded method with most specific type. SinceString
is more specific thenObject
that is the method that gets called.If you had another overload that was as specific as String, say
foo(Integer)
then you would get a ambiguous overload error.因为第二个使用 null 注释掉的调用对于编译器来说是不明确的。 文字 null 可以是字符串或对象。 而分配的值有明确的类型。 您需要强制转换 null,例如 test.foo((String)null) 以消除歧义。
Because the second commented out invocation with null is ambiguous to the compiler. The literal null could be a string or an object. Whereas the assigned value has a definite type. You need to cast the null, e.g. test.foo((String)null) to remove the ambiguity.