单元测试验证重载与重写,核心是检验调用行为:重载需覆盖参数组合、歧义场景及类型提升,确保编译期绑定正确;重写须用父类引用调用子类实例,验证运行期多态、协变返回及final/private/static方法不可重写等语义正确性。

写单元测试验证重载与重写,关键不是“测语法是否合法”,而是验证调用行为是否符合预期:重载看编译期是否选对方法,重写看运行期是否执行子类逻辑。Java 编译器和 JVM 本身会拦截明显错误(比如签名不符、private 方法被重写),但真正容易出错的是语义歧义、协变返回误用、或父类方法被意外绕过——这些必须靠测试暴露。
重载的测试重点:参数匹配是否准确
重载方法在编译时就绑定,测试要覆盖边界情况,防止编译器“猜错”或调用歧义:
-
显式传入每种参数组合:比如有
add(int, int)、add(double, double)、add(int, double),就得分别调用add(1, 2)、add(1.0, 2.0)、add(1, 2.0),并断言输出或返回值类型/值正确 -
主动触发歧义场景:例如定义了
process(String, int)和process(int, String),再调用process(null, 1)或process(1, null)——此时编译会报错Ambiguous method call,测试里应确保这类调用根本无法通过编译(即在 IDE 或 Maven 编译阶段失败,不进 JUnit) -
检查自动类型提升是否干扰意图:如只有
print(long)和print(String),调用print(5)会走long版本;若业务上希望整数字面量默认走String,就得补一个print(int)并在测试中验证
重写的测试重点:运行时多态是否生效
重写依赖对象实际类型,测试必须用向上转型后的引用来调用,才能检验动态分派是否正确:
-
用父类引用指向子类实例:例如
Animal a = new Dog(); a.makeSound();,断言输出是"Woof!"而非"Animal makes a sound" -
覆盖协变返回类型时验证实际类型:若父类返回
Animal,子类重写返回Dog,测试中应调用getAnimal()后用assertThat(...).isInstanceOf(Dog.class) -
避免直接用子类引用调用:写成
Dog d = new Dog(); d.makeSound();测试通过也没意义——这测的是方法存在性,不是重写机制
容易忽略但关键的测试点
这些不是语法问题,却是线上故障高发区:
立即学习“Java免费学习笔记(深入)”;
-
final / private / static 方法被“伪重写”:子类里声明同名方法不会覆盖,而是隐藏。测试时用父类引用调用,仍执行父类逻辑。可故意在子类加
@Override,看编译是否报错(IDE 或maven-compiler-plugin配置failOnError) - 接口默认方法被实现类重写:JDK 8+ 允许,但若实现类没重写,又没提供其他实现,会走接口默认逻辑。测试需覆盖“未重写”和“已重写”两种状态
-
泛型擦除导致的重载失效:如
handle(List<string>)</string>和handle(List<integer>)</integer>编译不通过(擦除后签名重复),测试前先确认编译能过,否则直接失败
不复杂但容易忽略:重载靠编译器选方法,测试得穷举输入;重写靠 JVM 查类型,测试得用父类引用来触发。写对了签名只是起点,跑对了用例才算落地。


















