java重载优先匹配基本类型而非包装类型,按精确匹配、拓宽转换、装箱/拆箱、varargs顺序解析;装箱歧义时需显式强转;包装类型用于null语义、泛型、反射等场景,但需注意性能与空指针风险。

Java 编译器在方法重载中选择版本时,**优先匹配基本类型,而不是包装类型**。这不是靠代码顺序或写法决定的,而是由编译期的重载解析规则严格控制的。
重载匹配有明确优先级
当多个重载方法参数类型不同,而传入的实参可适配多个时,编译器按以下顺序筛选最具体的方法:
-
精确匹配:比如传
int值,有void f(int)就直接选它,不考虑void f(Integer) -
拓宽转换(widening):如
int→long、char→int -
装箱或拆箱(boxing/unboxing):仅当前两步都失败时才尝试,例如传
int但只有f(Integer),才会自动装箱 - 可变参数(varargs):最后兜底,优先级最低
常见陷阱:装箱引发歧义
当多个包装类型方法同时存在,且都可通过装箱匹配,编译器无法确定唯一最优解,就会报错:
- 例如:
void log(Number n)和void log(Integer i),调用log(42)会编译失败 - 原因:42 可装箱为
Integer,也可先装箱再向上转型为Number,两者都属于第三级匹配,无法判定哪个“更具体” - 解决办法:显式强转,如
log((Integer)42)或log((Number)42);或删减冗余重载
什么时候必须用包装类型参与重载
不是为了“看起来更面向对象”,而是业务语义或技术限制要求:
-
需要表达 null 含义:比如数据库字段允许为空,用
Integer能区分“值为 0”和“未设置”,而int只能靠魔数补救 -
泛型或集合场景:如
List<integer></integer>、Map<string boolean></string>,基本类型语法非法 -
反射调用:目标方法参数是
Class>或声明为包装类时,传Integer更安全,避免拆箱空指针
性能与安全建议
别让方便掩盖代价:
- 循环里频繁用
Integer累加(如sum += i),每次都会隐式拆箱 + 运算 + 装箱,产生大量临时对象 - 比较两个
Integer请用.equals(),==在 -128~127 外会返回 false(缓存机制失效) - 可能为 null 的包装类型,拆箱前务必判空,或改用
OptionalInt等原始特化类型
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











