Java泛型中的协变和逆变
一般我们看Java泛型好像是不支持协变或逆变的,比如前面提到的List<Object>
和List<String>
之间是不可变的。但当我们在Java泛型中引入通配符这个概念的时候,Java 其实是支持协变和逆变的。
看下面几行代码:
-
// 不可变
-
List<Fruit>fruits =newArrayList<Apple>();// 编译不通过
-
// 协变
-
List<?extendsFruit>wildcardFruits =newArrayList<Apple>();
-
// 协变->方法的返回值,对返回类型是协变的:Fruit->Apple
-
Fruitfruit =wildcardFruits.get(0);
-
// 不可变
-
List<Apple>apples =newArrayList<Fruit>();// 编译不通过
-
// 逆变
-
List<?superApple>wildcardApples =newArrayList<Fruit>();
-
// 逆变->方法的参数,对输入类型是逆变的:Apple->Fruit
-
wildcardApples.add(newApple());
可见在Java泛型中通过extends
关键字可以提供协变的泛型类型转换,通过supper
可以提供逆变的泛型类型转换。
------------------越是喧嚣的世界,越需要宁静的思考------------------ 合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。 积土成山,风雨兴焉;积水成渊,蛟龙生焉;积善成德,而神明自得,圣心备焉。故不积跬步,无以至千里;不积小流,无以成江海。骐骥一跃,不能十步;驽马十驾,功在不舍。锲而舍之,朽木不折;锲而不舍,金石可镂。蚓无爪牙之利,筋骨之强,上食埃土,下饮黄泉,用心一也。蟹六跪而二螯,非蛇鳝之穴无可寄托者,用心躁也。