Java方法重载中,编译器优先选择实参与形参类型完全一致的精确匹配,不触发任何转换;无精确匹配时才按固定路径进行类型提升;包装类型不参与精确匹配,仅在基本类型无匹配时尝试装箱。

Java 方法重载中,基本类型参数的匹配优先级非常明确:**编译器永远优先选择精确匹配(exact match)的基本类型方法,不触发任何转换**。这不是“倾向”,而是编译规则强制要求——只要存在形参类型与实参静态类型完全一致的方法,就直接选定它,跳过后续所有转换尝试。
精确匹配是第一且唯一触发条件
所谓“精确匹配”,指实参的编译时类型与方法形参类型完全相同,包括:
- int 字面量(如 5)或 int 变量 → 匹配 void m(int x)
- long 字面量(如 5L)或 long 变量 → 匹配 void m(long x)
- char 字面量(如 'a')或 char 变量 → 匹配 void m(char x)
注意:即使声明了 m(Integer)、m(Number) 或 m(Object),只要 m(int) 存在,传入 5 就一定调用它,不会装箱、不会上转型、不会进 varargs。
没有精确匹配时才走类型提升,但不跨路径
当实参类型找不到完全对应的重载方法时,编译器才按固定路径尝试自动提升(widening),且只走一条最短合法路径:
立即学习“Java免费学习笔记(深入)”;
- byte → short → int → long → float → double
- char → int → long → float → double
- boolean 不参与任何提升;byte、short、char 之间互不转换
例如:
byte b = 10; 调用 m(b) —— 若只有 m(int) 和 m(long),则选 m(int)(一步提升),不会跳到 m(long)。
包装类型不参与“精确匹配竞争”,仅作兜底
Integer、Long 等包装类形参,天然无法与基本类型字面量构成精确匹配。它们只在以下两种情况下被考虑:
- 实参本身就是包装类型对象(如 Integer.valueOf(5)),且存在对应形参
- 所有基本类型和提升路径都无匹配时,才尝试装箱(如传 5,但只有 m(Integer) 和 m(String))
一旦混用基本类型和包装类型(如同时定义 m(int) 和 m(Integer)),传基本值永远走前者;但若删掉 m(int),再传 5,就会装箱调用 m(Integer)。
常见陷阱:null 和字面量容易误判“精确性”
null 没有类型,不能和任何基本类型匹配,所以 m(null) 永远不会调用 m(int);它只可能匹配引用类型版本,且多个互不继承的引用类型(如 m(String) 和 m(Integer))会导致编译错误。
而整数字面量如 10 默认是 int 类型,不是 byte 或 short —— 所以即使有 m(byte),m(10) 也不会调用它,除非显式强转:(byte)10。


















