Java协变返回类型允许子类重写父类方法时返回更具体的子类类型,仅适用于引用类型,基本类型和void必须严格一致,泛型不协变,需注意List<Dog>不是List<Animal>的子类。

子类重写父类方法时返回子类类型,是 Java 的协变返回(Covariant Return Type)特性,从 JDK 5 开始支持。它不是“配置”出来的,而是直接在子类方法声明中写出更具体的返回类型,编译器自动校验是否符合继承关系。
必须满足的条件
只有当父类方法返回的是引用类型(不能是基本类型或 void)时,子类才允许返回其子类类型。例如:
- 父类方法返回
Animal,子类可返回Dog(Dog extends Animal)✅ - 父类方法返回
Object,子类可返回String或ArrayList<String>✅ - 父类方法返回
int、void或double,子类必须严格一致,不能改成Integer或Long❌
正确写法示例
代码中直接写子类类型即可,无需额外注解或配置:
class Animal { }
class Dog extends Animal { }
class Zoo {
public Animal getAnimal() {
return new Animal();
}
}
class DogZoo extends Zoo {
@Override
public Dog getAnimal() { // ✅ 合法:Dog 是 Animal 的子类
return new Dog();
}
}
注意:@Override 注解虽非强制,但强烈建议加上——它能帮你在编译期立刻发现返回类型不合法、方法名拼错或参数不匹配等问题。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
立即学习“Java免费学习笔记(深入)”;
泛型返回值要特别小心
泛型本身不协变,所以即使 Dog 是 Animal 的子类,List<Dog> 也不是 List<Animal> 的子类:
- 父类返回
List<Animal>→ 子类不能返回List<Dog>❌ - 但可以返回
ArrayList<Dog>(前提是ArrayList是List的实现类,且方法签名中父类返回的是List接口)✅ - 更安全的做法是保持泛型类型一致,或改用具体类型(如返回
Dog而非List<Dog>)
常见错误提醒
以下写法都会编译失败:
- 父类返回
String,子类返回Object(范围扩大)❌ - 父类返回
int,子类返回Integer(基本类型和包装类不兼容)❌ - 忘了加
@Override,导致实际变成重载而非重写,运行时调用不到预期方法 ❌

















