打字猴:1.700447237e+09
1700447237
1700447238 }
1700447239
1700447240 此时,已经推断出List集合中取出的是E类型的元素。具体是什么类型的元素就要等到运行时才能确定了,但它一定是一个确定的类型,比如read(Arrays.asList(“A”))调用该方法时,可以推断出List中的元素类型是String,之后就可以对List中的元素进行操作了,如加入到另外的List<E>集合中,或者作为Map<E, V>的键等。
1700447241
1700447242 (2)泛型结构只参与“写”操作则限定下界(使用super关键字)先看如下代码是否可以编译:
1700447243
1700447244 public static void write(List<?extends Number>list){
1700447245
1700447246 //加入一个元素
1700447247
1700447248 list.add(123);
1700447249
1700447250 }
1700447251
1700447252 编译失败,失败的原因是list中的元素类型不确定,也就是编译器无法推断出泛型类型到底是什么,是Integer类型?是Double?还是Byte?这些都符合extends关键字的定义,由于无法确定实际的泛型类型,所以编译器拒绝了此类操作。
1700447253
1700447254 在此种情况下,只有一个元素是可以add进去的:null值,这是因为null是一个万用类型,它可以是所有类的实例对象,所以可以加入到任何列表中。
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
[ 上一页 ]  [ :1.700447237e+09 ]  [ 下一页 ]