Java逆变(Covariant)和协变(Contravariant)

1. 定义

逆变和协变描述的经过类型变换后的类型之间的关系。假如AB表示类型,f表示类型变换,A ≤B表示A是B的子类型,那么

  • 如果A ≤Bf(A) ≤f(B),那么f是协变
  • 如果A ≤Bf(B) ≤f(A),那么f是逆变
  • 如果两者都不是,那么f不变
    这里的子类型并非是面向对象中继承关系中的子类型,它更多的是描述两个类型之间的兼容性。

2. 实例:泛型

考虑一个例子,假如f(A) = List,且List声明如下:

class List { ... }

那么f是逆变,还是协变,又或者是不变?如果是协变意味着ListList的子类型,如果是逆变意味着ListList的子类型:

ArrayList strings = new ArrayList();   // error
ArrayList objects = new ArrayList();  // error
 
 

在Java中显然两者都不成立,所以说f是不变,且f表示泛型,即Java泛型是不变。

2. 实例:数组

再举个例子,假如f(A) = A[], 那么f是逆变,还是协变,又或者是不变?如果是协变意味着String[]Object[]的子类型,如果是逆变意味着Object[]String[]的子类型:

Object[] objects = new String[1];

可以看出,在Java中数组是协变。

你可能感兴趣的:(Java逆变(Covariant)和协变(Contravariant))