Java泛型中的协变和逆变

一般我们看Java泛型好像是不支持协变或逆变的,比如前面提到的​​List<Object>​​和​​List<String>​​之间是不可变的。但当我们在Java泛型中引入通配符这个概念的时候,Java 其实是支持协变和逆变的。

看下面几行代码:


 


  1. ​// 不可变​
  2. ​List<Fruit>fruits =newArrayList<Apple>();// 编译不通过​
  3. ​// 协变​
  4. ​List<?extendsFruit>wildcardFruits =newArrayList<Apple>();​
  5. ​// 协变->方法的返回值,对返回类型是协变的:Fruit->Apple​
  6. ​Fruitfruit =wildcardFruits.get(0);​
  7. ​// 不可变​
  8. ​List<Apple>apples =newArrayList<Fruit>();// 编译不通过​
  9. ​// 逆变​
  10. ​List<?superApple>wildcardApples =newArrayList<Fruit>();​
  11. ​// 逆变->方法的参数,对输入类型是逆变的:Apple->Fruit​
  12. ​wildcardApples.add(newApple());​

可见在Java泛型中通过​​extends​​关键字可以提供协变的泛型类型转换,通过​​supper​​可以提供逆变的泛型类型转换。



------------------越是喧嚣的世界,越需要宁静的思考------------------ 合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。 积土成山,风雨兴焉;积水成渊,蛟龙生焉;积善成德,而神明自得,圣心备焉。故不积跬步,无以至千里;不积小流,无以成江海。骐骥一跃,不能十步;驽马十驾,功在不舍。锲而舍之,朽木不折;锲而不舍,金石可镂。蚓无爪牙之利,筋骨之强,上食埃土,下饮黄泉,用心一也。蟹六跪而二螯,非蛇鳝之穴无可寄托者,用心躁也。