泛型方法

上一篇章我们出于类型安全的考虑,不建议使用原生类型,用List<?>代替使用,但是List<?>不允许添加除null以外的任何元素,因此我们需要使用泛型方法List<E>,如下:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class KnowGeneric {
 /*
  * 不允许添加除null以外的任何元素 The method addAll(Collection<? extends capture#1-of ?>) in
  * the type List<capture#1-of ?> is not applicable for the arguments
  * (List<capture#2-of ?>)
  */
 private static <E> List<?> wildCardAdd(List<?> list1, List<?> list2) {
 for (int i = 0; i < list2.size(); i++) {
 //判断过滤代码略
 list1.add(list2.get(i));
  }
 }
 private static <E> void geneAdd(List<E> list1, List<E> list2) {
 for (E e : list2) {
 //判断过滤代码略
 list1.add(e);
  }
 }
 /*

* 根据"producer-extends, consumer-super"法则

若从集合中获取数据,则该集合元素类型使用 ? extends E通配符

若往集合中插入数据,则使用 ? super E通配符

同时用于存取,不用通配符。

如下方法则选择一个参数使用通配符,保证list1可以兼容list2元素类型即可

你可以尝试下把list1类型改成List<? extends E>,不会编译通过,因为此时list1元素类型被指定为E的子类,我们不能确定子类是什么,是否与list2中的元素类型兼容。

   */
 private static <E> void boundedWildCardAdd(List<E> list1, List<? extends E> list2){
 for (E e : list2) {
 //判断过滤代码略
 list1.add(e);
  }
  System.out.println(list1.toString());
 }
 public static void main(String[] args) {
  List<Integer> inteList1 = new ArrayList<Integer>(Arrays.asList(11,22,33));
  List<Integer> inteList2 = new ArrayList<Integer>(Arrays.asList(44,55,66));
  List<Number> numList = new ArrayList<Number>(Arrays.asList(88,99,100));
 // 类型一致,没有错误和警告
 geneAdd(inteList1, inteList2);
 /*
   * List<Integer> 并不是List<Number>的子类
   * 编译错误:The method geneAdd(List<E>, List<E>) in the type KnowGeneric is not
   * applicable for the arguments (List<Number>, List<Integer>)
   */
 geneAdd(numList, inteList2);
 //编译通过
 boundedWildCardAdd(inteList1, inteList2);
 boundedWildCardAdd(numList, inteList2);
 }
}

geneAdd指定类型参数E,保证集合中数据类型一致,但geneAdd方法有个不足之处,那就是缺乏灵活性,两个方法参数E的类型都必须是一样的,我们可以用有界通配符,boundedWildCardAdd就是其中一个示例,根据"producer-extends, consumer-super"法则,你可以将类型参数改用super的形式表示,看看运行结果如何

 private static <E> void boundedWildCardAdd(List<? super E> list1, List<E> list2){

 for (E e : list2) {
 //判断过滤代码略
 list1.add(e);
  }
  System.out.println(list1.toString());
}

原文发布于微信公众号 - java达人(drjava)

原文发表时间:2016-05-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏WD学习记录

Python数据结构与算法笔记(2)

栈、队列、deques、列表是一类数据的容器,它们数据项之间的顺序由添加或删除的顺序决定。一旦一个数据项被添加,它相对于前后元素一直保持该位置不变。诸如此类的数...

1121
来自专栏用户2442861的专栏

java泛型(一)、泛型的基本介绍和使用

http://blog.csdn.net/lonelyroamer/article/details/7864531

1381
来自专栏用户2442861的专栏

深入理解java异常处理机制

http://blog.csdn.net/hguisu/article/details/6155636

892
来自专栏测试开发架构之路

总结了一些指针易出错的常见问题(四)

指针与结构体 简介:我们可以使用C的结构体来表示数据结构元素,比如链表或树的节点,指针是把这些元素联系到一起的纽带。 typedef struct _pers...

2967
来自专栏老九学堂

干货 | Java 中不得不知的异常和处理详解

简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常。异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用...

4027
来自专栏Kevin-ZhangCG

[ Java学习基础 ] Java异常处理

3306
来自专栏拭心的安卓进阶之路

深入理解 Java 泛型

首先提个问题: Java 泛型的作用是什么?泛型擦除是什么?泛型一般用在什么场景? 如果这个问题你答不上来,那这篇文章可能就对你有些价值。 什么是泛...

5359
来自专栏大闲人柴毛毛

深入理解java异常处理机制

 1. 引子        try…catch…finally恐怕是大家再熟悉不过的语句了,而且感觉用起来也是很简单,逻辑上似乎也是很容易理解。不过,...

2434
来自专栏大前端_Web

javascript语言精粹(蝴蝶书)-笔记

版权声明:本文为吴孔云博客原创文章,转载请注明出处并带上链接,谢谢。 https://blog.csdn.net/wkyseo/articl...

3633
来自专栏Java帮帮-微信公众号-技术文章全总结

【选择题】Java基础测试四(15道)

【选择题】Java基础测试四(15道) 41.以下哪项是接口的正确定义?( B D ) A、 interface B { void print...

4889

扫码关注云+社区

领取腾讯云代金券