重载Java:允许使用一个varargs参数的函数和具有相同名称和一个相同类型参数的函数?
在准备Java认证考试时,我非常惊讶地看到Java允许这样做:
public class Consumer {
public void buy(Object o) {
System.out.println("Buying one object");
}
public void buy(Object... o) {
System.out.println("Buying multiple objects");
}
public static void main(String[] args) {
Consumer consumer = new Consumer();
consumer.buy(new Object());
consumer.buy("a String");
}
}
这个类编译并运行良好。它打印“购买一件物品”两次。实际上,我想看到一个编译器错误,因为这两个函数都可以使用。编译器如何在这里选择最佳匹配函数?当我只传递一个参数时,它是否总是选择非varargs函数
# 1 楼答案
在特定情况下如果传递给此函数的参数是数组(还包括表示数组的逗号分隔语法),则编译器只会选择
buy(Object... o)
。例如:# 2 楼答案
方法重载解析分为3个阶段。只有在第三个也是最后一个阶段,它才会考虑使用varag的方法(例如
public void buy(Object... o)
),因此,如果在前两个阶段中的一个阶段中找到匹配方法,则会忽略varargs方法,并选择非varag匹配方法因此,这两个调用都会导致选择
public void buy(Object o)
当您只传递一个参数时,它将始终选择非varargs方法,除非该参数的编译时类型是数组:
传递
null
还将导致编译器选择varargs方法:以下是相关的JLS 15.12.2. Compile-Time Step 2: Determine Method Signature引用: