`
elite20130514
  • 浏览: 44778 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

读编写高质量代码整理(九)-警惕泛型不能协变和逆变

阅读更多

先引进两个名词“协变”、“逆变”

协变——用一个窄类型替换宽类型

逆变——用宽类型替换窄类型

 协变代码如下:

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>();

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics