先看协变和逆变的概念
如果某个返回的类型可以由其派生类型替换,那么这个类型就是支持协变的
如果某个参数类型可以由其基类替换,那么这个类型就是支持逆变的。
下面展示 例子
。
public static void main(String[]args) {
//数组支持协变
Number[] n = new Integer [10];
//编译不通过,泛型不支持协变
List<Number>In =new ArrayList<Integer>();
}
}
ArrayList是List的子类型,Integer是Number的子类型,LSP在此处行不通了,原因就是Java为了保证运行期的安全性,必须保证 泛型参数类型是固定的,所以它不允许一个泛型参数可以同时包含两种类型,即使是父子类的关系也不行。
那么如果我们想对泛型使用协变的特性怎么办呢?可以用通配符模拟协变:
List<? extends Number> In = new ArrayList<Integer>();
类似的泛型同样不支持逆变
那么如果我们想对泛型使用逆变的特性怎么办呢?可以用通配符模拟协变:
List<? super Integer> In = new ArrayList<Number>();