含long、int、short参数的重载方法意外歧义问题咨询
Java方法重载歧义问题解析
疑问列表
- 调用
method((short)1,1,1)时,为何仅在第2个和第3个方法间存在歧义,明明该调用也可隐式转换适配第1个方法? - 明明适配第3个方法所需的隐式转换更少,为何该调用仍存在歧义?
- 若隐式转换的次数无关紧要,为何调用
method(1,1,1)时不会在第1个和第2个方法间产生歧义,明明它也能隐式转换适配两者?
代码示例
public class Main { static void method(long x, long y, long z) { System.out.println("1"); } static void method(int x, long y, int z) { System.out.println("2"); } static void method(short x, int y, double z) { System.out.println("3"); } public static void main(String[] args) { method((short) 1, 1, 1); // ambiguous between 2 and 3 method(1, 1, 1); // calls 2 } }
问题1解答
Java方法重载解析的第一步是筛选可适用方法,但还会优先排除被其他候选方法「覆盖」的选项——如果存在某个方法的所有形参类型都比另一个方法的形参更具体,那么后者会被直接踢出候选列表。
对于method((short)1,1,1):
- 方法1的形参全是
long,而方法2的int、方法3的short/int都是比long更具体的基本类型,所以方法1被判定为非最优候选,直接排除,剩下的只有方法2和3。
问题2解答
Java的重载解析不看「转换次数多少」,而是看单个参数适配的优先级对比,只有当某方法的所有参数适配都不比另一个方法差,且至少有一个参数的适配更优时,才会被选为更合适的方法。
对比方法2和3的适配情况:
- 方法2:
short→int(拓宽转换)、int→long(拓宽转换)、int直接匹配 - 方法3:
short直接匹配、int直接匹配、int→double(拓宽转换)
这里方法2的第一个参数适配比方法3差(需要转换vs直接匹配),但第三个参数适配比方法3好(直接匹配vs需要转换);反过来方法3也是如此,没有哪个方法在所有参数的适配都占优势,因此编译器无法判断优先级,产生歧义。
问题3解答
调用method(1,1,1)时,候选方法是1和2:
- 方法2:第一个
int直接匹配、第二个int→long(拓宽转换)、第三个int直接匹配 - 方法1:三个
int都要转成long(拓宽转换)
此时方法2的每一个参数适配都不比方法1差,而且第一个和第三个参数的适配明显更优(直接匹配vs强制转换),所以编译器会判定方法2是更合适的候选,因此没有歧义,直接调用方法2。
内容的提问来源于stack exchange,提问作者nemidunam
相关产品推荐
相关产品推荐

