读编写高质量代码整理(九)-警惕泛型不能协变和逆变
程序员文章站
2024-03-14 19:37:34
...
先引进两个名词“协变”、“逆变”
协变——用一个窄类型替换宽类型
逆变——用宽类型替换窄类型
协变代码如下:
public class Base {
public Number doStuff() {
return 0;
}
}
class Sub extends Base {
@Override
public Integer doStuff() {
return 0;
}
}
逆变代码如下:
public class Base {
public void doStuff(Integer i) {
}
}
class Sub extends Base {
@Override
public void doStuff(Integer i) {
}
// overload
public void doStuff(Number num) {
}
}
协变即为多态,作者如是说“在java世界里,重复发明*的事情多了去了”!哈哈
但是。。。
泛型不支持协变,我很纳闷,为什么呢?
java机制问题,java为了保证运行时安全,必须保证泛型的类型是一致的,即使是父子类都不可以。
不过,泛型提供了一种通配符(Wildcard)模拟协变,代码如下:
List<? extends Number> ln = new ArrayList<Integer>();
? extends Number是什么意思呢?extends是继承的依稀,某某继承Number的意思是说,我只要是Number的一个子类就可以了,by the way,? super Integer是什么意思呢?猜出来了了,只要是Integer的父类皆可,这两者extends super合起来就构成泛型的边界喽!
泛型不支持逆变!同理可以通过通配符模拟,代码如下:
List<? super Integer> ln = new ArrayList<Number>();
上一篇: Linux grep命令的一些使用体会
下一篇: 对泛型的认识