让我们考虑这个例子
public class C {
public void method(String s, Integer i, Object... o) {
System.out.println("method(String s, Integer i, Object... o)");
}
public void method(Object o, Integer i) {
System.out.println("method(Object o, Integer i)");
}
}
执行时
C c = new C();
c.method("1", 1);
我期望method
的第一个实现会被调用,但我打印出了此消息
method(Object o, Integer i)
答案 0 :(得分:0)
这是因为您只发送了两个参数,所以将执行带有两个参数的方法,发送三个并且将执行带有三个参数的方法。
答案 1 :(得分:0)
首先,您必须了解OOP,多态和重载中的一种面向对象概念(及其Java语法)。无论如何,请致电
c.method("1", 1);
您实际上是在调用第二个方法本身,该方法接受2个参数,而不是第一个方法似乎具有3个或更多参数。该程序实际上正在执行预期的操作。
答案 2 :(得分:0)
如果需要调用第一个方法,请改用三个参数,因为var-args通常接受一个或任意数量的参数。因此,调用语句应如下所示:
c.method("1", 1,"any argument");
如果您只想使用两个参数调用第一个方法,请使用以下实现:
public class C {
public void method(String s, Object... o) {
System.out.println("method(String s, Integer i, Object... o)");
}
public void method(Object o, Integer i) {
System.out.println("method(Object o, Integer i)");
}
}
答案 3 :(得分:0)
您正在传递两个参数,因此具有2个参数的编译器将考虑第二个方法,因为参数的数量与第二个方法匹配,然后编译器检查参数的数据类型。 但是第二种方法的第一个预期参数是“ Object”,并且您正在传递“ String”。
答案 4 :(得分:0)
如Compile-Time Step 2: Determine Method Signature中所述:
第一阶段(第15.12.2.2节)执行重载解析,不允许装箱或拆箱转换,也不允许使用可变Arity方法调用。如果在此阶段未找到适用的方法,则处理将继续进行到第二阶段。
第二阶段(第15.12.2.3节)在允许装箱和拆箱的同时执行重载解析,但仍排除使用可变arity方法调用。如果在此阶段未找到适用的方法,则处理将继续进行到第三阶段。
第三阶段(第15.12.2.4节)允许将重载与可变arity方法,装箱和拆箱相结合。
因此,在第一阶段中,将选择不包含varargs的方法,因为它将是strictly-matched。
答案 5 :(得分:0)
确定方法的签名基于三个阶段:前两个阶段基于匹配的非args方法,而在第三个阶段中,考虑具有var-args的方法。
如果两个方法都被调用,则具有非var-args的方法将比具有var-args的方法具有更高的优先级
// least priority method if both method arguments matching with the calling one
public void method(String s, Integer i, Object... o) {
System.out.println("method(String s, Integer i, Object... o)");
}
public void method(Object o, Integer i) {
System.out.println("method(Object o, Integer i)");
}
这是规格:
Compile-Time Step 2: Determine Method Signature
- 第一阶段执行重载解析,不允许装箱或拆箱转换,或使用可变Arity方法调用。如果在此阶段未找到适用的方法,则处理将继续进行到第二阶段。
- 第二阶段执行重载解析,同时允许装箱和取消装箱,但仍禁止使用可变arity方法调用。如果在此阶段未找到适用的方法,则处理将继续进行到第三阶段。
- 第三阶段允许将重载与可变arity方法,装箱和拆箱相结合。
根据第三阶段规则:允许将重载与var-args组合,即,使用var-args的方法将具有较低的优先级