这只是一个练习,但我无法弄清楚这种模糊性:
private static void flipFlop(String str, int i, Integer iRef) {
System.out.println(str + "ciao");
}
private static void flipFlop(String str, int i, int j) {
System.out.println(str + "hello");
}
public static void main(String[] args) {
flipFlop("hello", new Integer(4), 2004);
}
Run Code Online (Sandbox Code Playgroud)
它说:
对于类型Test,方法flipFlop(String,int,Integer)是不明确的
我猜想第二个参数将被解包为int,所以第二个flipFlop方法就是选择.
Vid*_*dya 14
如果您喜欢精湛的阅读,这里是Java语言规范的相关部分,描述了如何解决方法.
但基本上你的第三个参数可以解释为原始或自动装箱的包装器,编译器无法弄清楚你想要什么.两种方法都是" 最具体 "的,以使用JLS术语.
Jer*_*vel 10
好吧,我已经仔细研究了JLS,我相信这应该可以解决你可能遇到的任何疑虑.
这是原始问题:
public class Main {
private static void flipFlop(int i, Integer iRef) {
System.out.println("Method 1");
}
private static void flipFlop(int i, int j) {
System.out.println("Method 2");
}
public static void main(String[] args) {
flipFlop(new Integer(4), 2004);
}
}
Run Code Online (Sandbox Code Playgroud)
正如在另一个答案中指出的那样:这会失败,因为编译器无法决定使用什么重载.
但是你可能认为这没有任何意义.编译器可以在这种情况下判断他应该使用什么方法:
public class Main {
private static void flipFlop(Integer y) {
System.out.println("ciao");
}
private static void flipFlop(int j) {
System.out.println("hello");
}
public static void main(String[] args) {
flipFlop(new Integer(6));
flipFlop(6);
}
}
Run Code Online (Sandbox Code Playgroud)
理性告诉我们,当你有值X+ Y和两个分别采用Y+ X和Y+的方法Y并且你知道X并且Y可以互换时,那么这意味着后一种方法更具体.
这两者之间的差异在JLS中描述.我在下面提供了整个工作流程,但重要的是:
首先,编译器将查看具有相同签名的方法,同时禁止装箱/取消装箱.在我们的第二个例子中,这不会导致任何问题,但在我们的第一个例子中,这并没有返回一个令人满意的方法,因为它们都没有Integer作为第一个参数.
当失败时,编译器继续进行允许装箱/拆箱的第二步.这应该解决我们对第一个参数的问题,但是现在引起第二个参数的歧义,因为现在不确定你是指使用一个int还是一个使用的过载Integer.
这最终导致模糊的方法调用.
第一阶段(§15.12.2.2)执行重载解析而不允许装箱或拆箱转换,或使用变量arity方法调用.如果在此阶段没有找到适用的方法,则处理继续到第二阶段.
第二阶段(§15.12.2.3)执行重载解析,同时允许装箱和拆箱,但仍然排除使用变量arity方法调用.如果在此阶段没有找到适用的方法,则处理继续到第三阶段.
如果方法可访问且适用,并且没有其他适用且可访问的方法严格更具体,则称该方法对于方法调用是最大特定的.
可能没有方法是最具体的,因为有两种或更多种方法是最具体的.在这种情况下:
如果所有最大特定方法都具有覆盖等效(§8.4.2)签名,那么:(......一些规则来决定谁被选中......)
否则,我们说方法调用是不明确的,并且发生编译时错误.
| 归档时间: |
|
| 查看次数: |
1060 次 |
| 最近记录: |