可变参数方法可重载但须避免歧义和硬性冲突:禁止与同类型数组方法共存、禁止仅靠参数个数差异重载、禁止仅返回值不同重载;安全重载需参数类型本质不同,匹配优先级为精确匹配>类型提升>装箱拆箱>可变参数。

可变参数方法可以重载,但必须严格遵守编译器的匹配规则和语法限制,否则会直接编译失败。核心原则是:不能产生歧义,且不能与数组参数方法共存。
重载时必须避开的硬性冲突
以下三类组合在同一个类中不允许同时存在,编译器会报错:
-
可变参数方法 + 同类型数组参数方法(如
hello(String...)和hello(String[]))——编译器认为签名重复,直接拒绝 -
两个可变参数方法,仅靠参数个数差异重载(如
hello(String...)和hello(String, String...))——调用hello("a","b","c")时无法确定选哪个,报“reference to hello is ambiguous” -
仅靠返回值不同进行重载(如
int sum(int...)和long sum(int...))——Java不支持,编译失败
安全可行的重载写法
真正能共存的重载,关键在于参数类型列表有本质区别,例如:
-
void print(String s)(固定单个字符串)void print(String... strs)(零到多个字符串)
调用print("hi")匹配第一个;print("a", "b")匹配第二个 -
void log(int level, String... msgs)(带固定级别+可变消息)void log(String tag, String... msgs)(带固定标签+可变消息)
参数类型开头不同(intvsString),无歧义 -
void process(List<string> list)</string>void process(String... items)
泛型擦除后签名不同(ListvsString[]),可共存
调用时的匹配优先级
编译器按固定顺序选择重载版本,从高到低:
-
精确匹配:参数类型、个数完全一致(如传
"x"调用method(String)) -
自动类型提升:如
byte→int,char→int -
装箱/拆箱:如
int→Integer - 可变参数:兜底选项,只在前三种都不满足时才考虑
例如同时存在 f(int)、f(Integer)、f(int...),调用 f(5) 一定走第一个,不会降级到可变参数。
实用调用方式
可变参数方法支持四种合法调用形式,本质都是传递数组:
- 不传参数:
sum()→ 等价于传入空数组new int[]{} - 传单个值:
sum(10)→ 等价于new int[]{10} - 传多个值:
sum(1, 2, 3)→ 等价于new int[]{1,2,3} - 传数组对象:
sum(new int[]{1,2,3,4})—— 直接复用已有数组,避免新建
注意:null 作为实参时需谨慎。若只有 f(String) 和 f(String...),f(null) 会匹配前者;但若再加一个 f(String[]),则变成二义性错误。










