重载方法选择

时间:2019-04-22 05:35:35

标签: java overloading variadic-functions

让我们考虑这个例子

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)

我从specs中了解到,phase 1中未考虑带有可变参数(变量)的方法,但是这种说法对我来说并不直观。

6 个答案:

答案 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

  
      
  1. 第一阶段执行重载解析,不允许装箱或拆箱转换,或使用可变Arity方法调用。如果在此阶段未找到适用的方法,则处理将继续进行到第二阶段。
  2.   
  3. 第二阶段执行重载解析,同时允许装箱和取消装箱,但仍禁止使用可变arity方法调用。如果在此阶段未找到适用的方法,则处理将继续进行到第三阶段。
  4.   
  5. 第三阶段允许将重载与可变arity方法,装箱和拆箱相结合。
  6.   

根据第三阶段规则:允许将重载与var-args组合,即,使用var-args的方法将具有较低的优先级