一尘不染

叫哪个方法?(整数... a)vs.(整数a,整数b)

java

我刚刚发现了一个非常有趣的Java技巧:

void method1(Integer... a){
}

因此,您可以根据需要为该方法提供尽可能多的整数。

现在,如果我有一个类似的(重载)方法,例如:

void method1(int a, int b){

}

当我执行以下行时,运行哪种方法:

method1(1, 2);

好吧,我可以通过使用不同的方法指令进行测试来轻松地发现这一点,但是当我考虑“重载”方法中的“规则”时,我必须确保每个重载的方法都必须相同,以便编译器知道确切地使用哪个。

我认为,上面的代码不起作用,因为应该混淆编译器。但是,当我尝试它时,它会起作用。

所以..有人知道这方面的更多背景信息吗?


阅读 166

收藏
2020-12-03

共1个答案

一尘不染

为了确定应调用哪种方法,编译器会遍历以下列表,如JLS#5.3JLS#15.12.2中所述

  • 身份转换(§5.1.1) = >method1(int a, int b)
  • 不断扩大的原始转换(第5.1.2节)
  • 扩展参考转换(第5.1.5节)
  • 装箱转换(第5.1.7节)(可选),然后加宽参考转换 == >method1(Integer... a)
  • 取消装箱转换(第5.1.8节),然后可以选择加宽原始转换。

在您的情况下,第一点适用并被method1(int, int)调用。

(更精确地说,你的方法使用varags并具有较低的优先级比简单的装箱转换。换句话说,如果有一个method1(Integer a, Integer b)会来之前method1(Integer... a)的层次)

为什么会这样呢?15.12.2中的注释提示:

这样可以保证,由于引入了可变arity方法,隐式装箱和/或拆箱,在Java SE 5.0之前在Java编程语言中有效的任何调用都不会被认为是模棱两可的。

2020-12-03