为何调用myMethod(1,100,'b')未编译报错却执行Version 1?
问题解析:为什么obj.myMethod(1, 100, 'b')没有触发编译错误反而执行了Version 1?
这问题问得很到位,我刚看到的时候也会琢磨下——明明第二个参数是int,第一个方法的第二个参数是double,为啥没报错还成功匹配了?别着急,咱们一步步拆解Java方法重载的匹配规则就清楚了。
首先先看你的代码:
class Demo { public void myMethod(int a, double b, char c) { System.out.println("Version 1."); } public void myMethod(int a, double b, double c) { System.out.println("Version 2."); } public void myMethod(int a, boolean b, double c) { System.out.println("Version 3."); } public void myMethod(int a, boolean b, boolean c) { System.out.println("Version 4."); } public static void main(String[] args) { Demo obj = new Demo(); obj.myMethod(1, 100, 'b'); } }
你疑惑的核心点在于:100是int类型,第一个方法的第二个参数是double,为什么能合法匹配?这就要说到Java的基本类型自动拓宽转换和重载方法的优先级匹配逻辑:
重载方法的匹配优先级:Java编译器在挑选重载方法时,会按以下顺序查找:
- 优先找所有参数都完全匹配的方法;
- 如果没有,找只需要一次自动拓宽转换就能匹配所有参数的方法;
- 再往后才会考虑装箱/拆箱、多次转换这类更复杂的情况。
针对你的调用逐个参数分析:
- 第一个参数
1是int,四个方法的第一个参数都是int,完全匹配,这一步所有方法都符合; - 第二个参数
100是int,Java允许int自动拓宽转换为double(这是基本类型转换里的合法操作,不需要强制转换); - 第三个参数
'b'是char,第一个方法的第三个参数正好是char,完全匹配。
- 第一个参数
对比其他候选方法:
- Version 2需要把第三个参数char转成double(一次转换),加上第二个参数int转double(一次转换),总共需要两次转换,优先级比只需要一次转换的Version 1低;
- Version 3和4的第二个参数是boolean,Java不允许int自动转换为boolean,所以这两个方法直接被排除在候选列表之外。
所以编译器最终会选择匹配程度最高的Version 1,而不是触发编译错误——因为存在合法的自动转换路径,而且找到了最优匹配的方法。
内容的提问来源于stack exchange,提问作者user8805424
相关产品推荐
相关产品推荐

