打字猴:1.700447255e+09
1700447255
1700447256 Object是否也可以?不可以,因为它不是Number子类,而且即使把list变量修改为List<?extends Object>类型也不能加入,原因很简单,编译器无法推断出泛型类型,加什么元素都是无效的。
1700447257
1700447258 在这种“写”操作的情况下,使用super关键字限定泛型类型的下界才是正道,代码如下:
1700447259
1700447260 public static void write(List<?super Number>list){
1700447261
1700447262 list.add(123);
1700447263
1700447264 list.add(3.14);
1700447265
1700447266 }
1700447267
1700447268 甭管它是Integer类型的123,还是Float类型的3.14,都可以加入到list列表中,因为它们都是Number类型,这就保证了泛型类的可靠性。
1700447269
1700447270 对于是要限定上界还是限定下界,JDK的Collections.copy方法是一个非常好的例子,它实现了把源列表中的所有元素拷贝到目标列表中对应的索引位置上,代码如下:
1700447271
1700447272 public static<T>void copy(List<?super T>dest, List<?extends T>src){
1700447273
1700447274 for(int i=0;i<srcSize;i++)
1700447275
1700447276 dest.set(i, src.get(i));
1700447277
1700447278 }
1700447279
1700447280 源列表是用来提供数据的,所以src变量需要限定上界,带有extends关键字。目标列表是用来写入数据的,所以dest变量需要界定上界,带有super关键字。
1700447281
1700447282 如果一个泛型结构即用作“读”操作又用作“写”操作,那该如何进行限定呢?不限定,使用确定的泛型类型即可,如List<E>。
1700447283
1700447284
1700447285
1700447286
1700447287 编写高质量代码:改善Java程序的151个建议 [:1700438170]
1700447288 编写高质量代码:改善Java程序的151个建议 建议97:警惕泛型是不能协变和逆变的
1700447289
1700447290 什么叫协变(covariance)和逆变(contravariance)?Wiki上是这样定义的:
1700447291
1700447292 Within the type system of a programming language, covariance and contravariance refers to the ordering of types from narrower to wider and their interchangeability or equivalence in certain situations(such as parameters, generics, and return types).
1700447293
1700447294 在编程语言的类型框架中,协变和逆变是指宽类型和窄类型在某种情况下(如参数、泛型、返回值)替换或交换的特性,简单地说,协变是用一个窄类型替换宽类型,而逆变则是用宽类型覆盖窄类型。其实,在Java中协变和逆变我们已经用了很久了,只是我们没发觉而已,看如下代码:
1700447295
1700447296 class Base{
1700447297
1700447298 public Number doStuff(){
1700447299
1700447300 return 0;
1700447301
1700447302 }
1700447303
1700447304 }
[ 上一页 ]  [ :1.700447255e+09 ]  [ 下一页 ]