Java父类引用调用协变返回类型重写方法为何报类型不兼容
问题成因
- Java 是静态类型语言,编译阶段只会根据变量的声明类型做类型检查,不会感知运行时的实际对象类型:你声明的变量
f的类型是父类F,所以编译器解析f.test()时,只会参考F类中定义的test()方法签名,判定该方法的返回值类型为AnotherFather。 - 协变返回类型是子类重写方法的语法特性,仅允许子类重写方法时返回原返回类型的子类,不会改变父类定义中方法的返回类型约束:你通过父类类型引用调用方法时,方法返回值的编译阶段类型永远以父类定义的签名为准,和子类重写时的协变返回类型无关。
- 把编译类型为
AnotherFather的返回值直接赋值给AnotherSon类型的变量,属于父类引用向子类引用的向下转型,没有显式强转的情况下,编译器会直接判定为类型不兼容,抛出编译错误。
修复方案
添加显式向下转型即可,运行阶段因为f.test()实际返回的是AnotherSon实例,强转不会抛出异常:
AnotherSon as = (AnotherSon) f.test();
内容的提问来源于stack exchange,提问作者MMMMMCCLXXVII
相关产品推荐
相关产品推荐

