Java 重载:对调用的引用不明确
Java overloading: reference to call ambiguous
考虑以下示例代码:
public class TestClass {
public void doSth(String str, String l, Object... objects) {
System.out.println("A");
}
public void doSth(String str, Object... objects) {
System.out.println("B");
}
}
当我现在调用 new TestClass().doSth("foo", "bar")
时,我得到了预期的结果 A
。但是,如果我通过将参数 l
更改为原始类型来更改第一个方法的方法签名:
public class TestClass {
public void doSth(String str, long l, Object... objects) {
System.out.println("A");
}
public void doSth(String str, Object... objects) {
System.out.println("B");
}
}
调用 new TestClass().doSth("foo", 2L)
将产生 reference to call ambiguous
编译时错误。
我考虑了一段时间,也咨询了 this Whosebug question,但我无法理解为什么会这样。在我看来,doSth("foo", 2L)
更具体到 doSth(String string, long l, Object... obj)
签名,应该允许编译器也得出这个结论。
在这种情况下,自动装箱会让您很伤心。具有讽刺意味的是,在那之前你是对的 - "long" 版本很容易被选中。
基本上,编译器知道它可以从您的值创建一个 Long,当然,它是一个对象。所以它仍然很困惑,因为可以使用长版本或长版本。一个 "better" 比另一个好吗?也许吧,但这是一条很好的线。
在这种情况下,我只能报告我的观察结果,而不是关于为什么 Java 如此表现的确切论证。
首先,将方法更改为
void doSth(long l) {...}
void doSth(Object o) {...}
解决了这个问题,即 doSth(2L);
将产生预期的结果。
更进一步,将方法参数更改为可变参数
void doSth(long... ls) {...}
void doSth(Object... os) {...}
与调用 doSth(2l);
一起产生与 OP 报告的相同的编译错误。
现阶段我的建议是将参数封装到数组中,再加上自动装箱会造成破坏。我对 JLS 的了解还不够充分,无法正确解释这一点。
考虑以下示例代码:
public class TestClass {
public void doSth(String str, String l, Object... objects) {
System.out.println("A");
}
public void doSth(String str, Object... objects) {
System.out.println("B");
}
}
当我现在调用 new TestClass().doSth("foo", "bar")
时,我得到了预期的结果 A
。但是,如果我通过将参数 l
更改为原始类型来更改第一个方法的方法签名:
public class TestClass {
public void doSth(String str, long l, Object... objects) {
System.out.println("A");
}
public void doSth(String str, Object... objects) {
System.out.println("B");
}
}
调用 new TestClass().doSth("foo", 2L)
将产生 reference to call ambiguous
编译时错误。
我考虑了一段时间,也咨询了 this Whosebug question,但我无法理解为什么会这样。在我看来,doSth("foo", 2L)
更具体到 doSth(String string, long l, Object... obj)
签名,应该允许编译器也得出这个结论。
在这种情况下,自动装箱会让您很伤心。具有讽刺意味的是,在那之前你是对的 - "long" 版本很容易被选中。
基本上,编译器知道它可以从您的值创建一个 Long,当然,它是一个对象。所以它仍然很困惑,因为可以使用长版本或长版本。一个 "better" 比另一个好吗?也许吧,但这是一条很好的线。
在这种情况下,我只能报告我的观察结果,而不是关于为什么 Java 如此表现的确切论证。
首先,将方法更改为
void doSth(long l) {...}
void doSth(Object o) {...}
解决了这个问题,即 doSth(2L);
将产生预期的结果。
更进一步,将方法参数更改为可变参数
void doSth(long... ls) {...}
void doSth(Object... os) {...}
与调用 doSth(2l);
一起产生与 OP 报告的相同的编译错误。
现阶段我的建议是将参数封装到数组中,再加上自动装箱会造成破坏。我对 JLS 的了解还不够充分,无法正确解释这一点。