Java方法重载和varargs

昆德加德

我试图了解方法重载,并且我有这些方法。

public void method(int a){
    System.out.println("int a");
}

//implementing interface method
@Override
public void method() {
    System.out.println("interface");
}

//varargs
public void method(int ... a){
    System.out.println("int ... a");
}

使用这些参数调用它们之后,

int[] a = new int[5];
stack.method();
stack.method(1);
stack.method(5,6);
stack.method(null);
stack.method(a);

我有这些结果:

接口
int
int ...
int ...
int ... a

据我所知,由于模棱两可,程序不应该编译,但是无论如何它还是可以编译的。编译器不应该抛出错误吗?

他们是

方法重载解决方案分为三个阶段。第一阶段和第二阶段不会将使用varargs的方法(也称为可变arity方法)视为候选方法,因此只有在未找到没有varargs的匹配方法的情况下,编译器才会将使用varargs的方法视为候选方法。

因此,在第一个和第二个方法调用中,您将void method(int ... a)被忽略,并且没有歧义。

15.12.2。编译时步骤2:确定方法签名

第二步在上一步中确定的类型中搜索成员方法。此步骤使用方法的名称和参数表达式来定位可访问和适用的方法,即可以在给定参数上正确调用的声明。

这种方法可能不止一种,在这种情况下,选择了最具体的一种。最特定方法的描述符(签名加返回类型)是在运行时用于执行方法分派的描述符。

如果通过严格调用(§15.12.2.2),松散调用(§15.12.2.3)或可变arity调用(§15.12.2.4)之一应用方法,则该方法适用。

某些包含隐式类型的lambda表达式(§15.27.1)或不精确的方法引用(§15.13.1)的参数表达式将被适用性测试忽略,因为在选择目标类型之前,无法确定其含义。

尽管方法调用可以是多边形表达式,但是只有其参数表达式(而不是调用的目标类型)会影响适用方法的选择。

确定适用性的过程始于确定可能适用的方法(第15.12.2.1节)。

该过程的其余部分分为三个阶段,以确保与Java SE 5.0之前的Java编程语言版本兼容。这些阶段是:

  1. 第一阶段(第15.12.2.2节)执行重载解析,不允许装箱或拆箱转换,也不允许使用可变Arity方法调用如果在此阶段未找到适用的方法,则处理将继续进行到第二阶段。这样可以保证,由于引入了可变arity方法,隐式装箱和/或拆箱,在Java SE 5.0之前的Java编程语言中有效的任何调用都不会被认为是模棱两可的。但是,声明可变可变方法(第8.4.1节)可以更改为给定方法方法调用表达式选择的方法,因为可变可变方法在第一阶段被视为固定可变方法。例如,在已经声明了m(Object)的类中声明m(Object ...)会导致不再为某些调用表达式(例如m(null))选择m(Object),例如m(Object [] )更具体。

  2. 第二阶段(第15.12.2.3节)在允许装箱和拆箱的同时执行重载解析,但仍排除使用可变arity方法调用。如果在此阶段未找到适用的方法,则处理将继续进行到第三阶段。这样可以确保如果通过固定arity方法调用适用方法,则永远不会通过可变arity方法调用选择方法。

  3. 第三阶段(第15.12.2.4节)允许将重载与可变arity方法,装箱和拆箱相结合

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章