Java类中如何使用逆变?定义逆变泛型类遇语法错误求助
Java泛型逆变的正确实现方式
问题根源
你在定义ContravariantAnimalHolder时写了<T super Cat>,这是语法错误——Java的泛型类型参数声明不支持super约束,super只能作为通配符(比如? super Cat)用在变量声明、方法参数等场景里,用来实现逆变逻辑。
逆变的正确实现思路
逆变的核心逻辑是:如果A是B的超类,那么Holder<A>可以被当作Holder<B>的超类型使用(简单说就是能把Holder<A>赋值给需要Holder<B>的变量)。在Java里,我们通过**通配符? super Cat**来实现这种关系,而不是在类定义时给类型参数加super约束。
步骤1:修正逆变持有者类的定义
先写一个普通的泛型类,不要加super约束:
public class ContravariantAnimalHolder<T> { private T animalHolder; // 逆变场景的核心是"消费"数据,所以只保留写入方法 public void setAnimalHolder(T animalHolder) { this.animalHolder = animalHolder; } // 注意:逆变场景下不建议提供get方法——因为get出来的类型是T的超类型,无法确定具体类型,使用时会不安全 }
步骤2:在使用时用通配符实现逆变
在变量声明或方法参数里用? super Cat来体现逆变关系:
public class VarianceMain { public static void main(String[] args) { // 逆变:ContravariantAnimalHolder<Animal>可以赋值给ContravariantAnimalHolder<? super Cat> ContravariantAnimalHolder<Animal> animalHolder = new ContravariantAnimalHolder<>(); ContravariantAnimalHolder<? super Cat> catHolder = animalHolder; // 可以安全传入Cat或其子类(比如Lion) catHolder.setAnimalHolder(new Cat()); catHolder.setAnimalHolder(new Lion()); // 如果一定要get,返回类型只能是Object,因为? super Cat的上界是Object // Object obj = catHolder.getAnimalHolder(); } }
为什么类定义不能用T super Cat?
Java泛型的类型参数声明只支持extends约束(指定类型参数的上界),不支持super约束(下界)。super通配符的设计初衷是在使用泛型实例时,表达"可以接受该类型及其所有超类型"的逆变关系,而不是用来定义泛型类本身的类型参数范围。
协变vs逆变的典型场景
- 协变:用
? extends T,适合生产型场景(只获取数据,比如你写的CovariantAnimalHolder的getAnimalHolder方法),能安全获取T或其子类型的实例。 - 逆变:用
? super T,适合消费型场景(只写入数据,比如上面的setAnimalHolder方法),能安全写入T或其子类型的实例。
内容的提问来源于stack exchange,提问作者user16422658
相关产品推荐
相关产品推荐

